It may be useful to define a pair of type aliases to make it more explicit what all of these arrows and brackets do:
type F1 ab = a -> b -- type synonym for single-argument functions type List a = [a] -- type synonym for lists
now you can write a signature of type map as:
map :: F1 st -> List s -> List t
which, if you are more familiar with Java or C ++ or any other, looks syntactically more similar:
List<T> map(F1<S, T> fun, List<S> list);
So you might think so: map takes a function and a list and returns another list. However, since functions are executed in Haskell, you do not need to pass all parameters at once. You can leave with a partial application of map only to its first argument. So really his type signature is more like:
F1<List<S>, List<T>> map(F1<S, T> fun);
... which, when you call map with just one argument to fun , gives you something like:
List<T> mapFun(List<S> list);
So, back to Haskell: you can read map :: (s -> t) -> [s] -> [t] either as:
- "
map takes a function from s to t and a list of s and returns a list of t" - "
map takes a function from s to t and turns it into a function from list s to list t"
The first is beautiful; the latter is more useful.
mergeconflict
source share