0

I'd like to achieve the following but can't fix the error: "Non-nominal type 'Element' does not support explicit initialization"

Original attempt:

public extension Array where Element: FloatingPointMathType {


    func mean<Element>() -> Element  {
        let sum: Element = reduce (0.0, +) as! Element

        return sum / Element(count) // ==> Non-nominal type 'Element' does not support explicit initialization
    }
}

Also, I wonder why it requires the as! Element cast

As a comparaison, a local function as follows compiles with no issue:

    func mean<Element: FloatingPointMathType>(_ e: [Element]) -> Element  {
        let sum: Element = e.reduce (0.0, +)

        return sum / Element(e.count)
    }
Stéphane de Luca
  • 12,745
  • 9
  • 57
  • 95
  • 1
    Related: https://stackoverflow.com/questions/28288148/making-my-function-calculate-average-of-array-swift – vadian Mar 28 '20 at 16:32
  • 2
    is `FloatingPointMathType` a new protocol? What is your Swift version? Note that `mean` is very misleading inside a collection extension. You are creating a new generic type that has nothing to do with the collection Element – Leo Dabus Mar 28 '20 at 16:33
  • Swift 5 / Xcode 11.3.1 – Stéphane de Luca Mar 28 '20 at 16:34

1 Answers1

0

It's impossible to say what the problem is exactly, because we don't know how your FloatingPointMathType protocol is defined. There are a few issues in your implementation (chiefly, you don't want to define a generic function mean<Element>; the extension is already parametrized over the Element type, and the generic parameter is introducing a new type name that shadows it (and that new type is unbound, so you can't do anything with it).

The following works with the standard library's FloatingPoint protocol:

public extension Collection where Element: FloatingPoint {
  func mean() -> Element  {
    reduce(into: 0, +=) / Element(count) 
  }
}
Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
  • 2
    Note that this would return `nan` for empty arrays – Leo Dabus Mar 28 '20 at 16:41
  • Yeah, there's no well-defined statistical mean of an empty collection; nan is the most sensible result for most contexts, but you may want to detect an empty collection and return zero in some cases instead. Alternatively, you could return an Optional instead and produce nil when the collection is empty. – Stephen Canon Mar 28 '20 at 16:45
  • Thanks @StephenCanon for the answer (Though I don't get your ref to C++). As Per the `NaN`, the code was the lean version of my implementation to demo the issue I was facing. – Stéphane de Luca Mar 28 '20 at 16:47