定义几个类型别名可能会有所帮助,以使所有这些箭头和括号的作用更加明确:
type F1 a b = a -> b -- type synonym for single-argument functions
type List a = [a] -- type synonym for lists
所以现在你可以将map的类型签名写成:
map :: F1 s t -> List s -> List t
如果您更熟悉 Java 或 C++ 或其他什么,它在语法上看起来更像:
List<T> map(F1<S, T> fun, List<S> list); // applies fun to each element in list
所以你可以这样想:map 接受一个函数和一个列表,然后返回另一个列表。但是,由于函数在 Haskell 中是 curried,因此您不必一次传递所有参数。您可以部分应用 map 来解决它的第一个参数。所以实际上它的类型签名更像是:
F1<List<S>, List<T>> map(F1<S, T> fun); // returns a function that applies fun to each element in a list
...当您使用 fun 参数调用 map 时,它会为您提供类似于以下内容的内容:
List<T> mapFun(List<S> list); // applies fun to each element in list
现在回到 Haskell:您可以将 map :: (s -> t) -> [s] -> [t] 读为:
- "
map 接受一个从 s 到 t 的函数,以及一个 s 的列表,并返回一个 的列表t"
- "
map 将一个函数从 s 转换为 t,并将其转换为一个从 s 列表到 的函数em>t 列表"
前者很好;后者更有帮助。