It's not clear to me why it's necessary to include <T, U> at the start of the function definition. In Haskell, unquantified type variables are implicitly universally quantified, i.e. you assume that the signature must be valid for any types T and U.
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.
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
or even which is already pretty close to the Haskell equivalent Arguably, Haskell syntax could be improved with more built-in syntax though I haven't thought about what this means for parsing the language.