func <^><T, U>(f: T -> U, a: T?) -> U? {
return a.map(f)
}
Gnartown! func <^><T, U>(f: T -> U, a: T?) -> U? {
return a.map(f)
}
Gnartown!For someone used to C-syntax, I guess the main deviation is that the return type is in the back and that there's a func keyword. As for the operaters, there is the addition of generics (what is wrong about <> ?), -> to describe signature of a function (a very sensible choice IMO) and ? for Optionals (again, fine for me).
I don't really see how a statically typed language can substantially improve this, but I'd be happy if someone can proof me wrong :-)
That's the only thing I think could be substantially improved, though. Personally I find the style where you separate the type signature from the function definition easier to read, for example
How about
<^> : (T -> U) * T? -> U?
<^> (f, a) {
return a.map(f)
}
or even <^> : (T -> U) * T? -> U?
<^> (f, a) -> a.map(f)
which is already pretty close to the Haskell equivalent (<^>) :: (t -> u) -> Maybe t -> Maybe u
(<^>) = fmap
Arguably, Haskell syntax could be improved with more built-in syntax <^> : (t -> u) -> t? -> u?
<^> = fmap
though I haven't thought about what this means for parsing the language.If I make a typo when using a type parameter in a function definition, can I accidentally introduce an extra type parameter?
No.
> If I make a typo when using a type parameter in a function definition, can I accidentally introduce an extra type parameter?
You couldn't introduce a new concrete type. You could introduce a new type variable, but the type signature would still have to typecheck, so it would difficult to come up with a non-contrived example where that would happen.
So it's true that in the Swift examples, you would need a convention to distinguish type variables from concrete types, or else you need to explicitly mark them as generic.