[英]Haskell: beginner function syntax confusion
I'm currently trying to learn Haskell, but I'm struggling with understanding the syntax. 我目前正在尝试学习Haskell,但我正在努力理解语法。 For example, take the
map
function: 例如,采取
map
功能:
map :: (s -> t) -> [s] -> [t]
map f [] = []
map f (x:xs) = f x : map f xs
I understand what the function does, and that map
has a function f :: s -> t
as a parameter. 我理解该函数的作用,并且该
map
具有函数f :: s -> t
作为参数。 But I read map :: (s -> t) -> [s] -> [t]
as "map is a function which maps a function mapping from s to t to s and then to t", which is obviously wrong. 但我读
map :: (s -> t) -> [s] -> [t]
为“map是一个函数,它将函数映射从s映射到s再映射到s然后再映射到t”,这显然是错误的。 Could someone clear this up for me? 有人可以为我清除这个吗?
The type (s -> t) -> [s] -> [t]
can be read in two ways. 类型
(s -> t) -> [s] -> [t]
可以通过两种方式读取。 One way is to treat it as a function of two arguments, the first a function of type s -> t
and the second a list of type [s]
. 一种方法是将其视为两个参数的函数,第一个是
s -> t
类型s -> t
函数,第二个是类型[s]
的列表。 The return value is of type [t]
. 返回值的类型为
[t]
。
The other way is to understand that function arrows are right-associative, so the type is equivalent to (s -> t) -> ([s] -> [t])
. 另一种方法是理解函数箭头是右关联的,因此类型等价于
(s -> t) -> ([s] -> [t])
。 Under this interpretation, map
is a function that takes a function from element to element s -> t
and turns it into a function from list to list [s] -> [t]
. 在这种解释下,
map
是一个函数,它将一个函数从元素转换为元素s -> t
并将其转换为一个函数,从列表到列表[s] -> [t]
。
Similarly, when using the function, you can think of map foo xs
as applying the function map
to two arguments foo
and xs
. 类似地,在使用该函数时,您可以将
map foo xs
视为将函数map
应用于两个参数foo
和xs
。 Or, since function application is left -associative, you can think of it as (map foo) xs
, applying map
to the single argument foo
to get back a new function which you then apply to xs
. 或者,由于函数应用程序是左关联的,您可以将其视为
(map foo) xs
,将map
应用于单个参数foo
以获取然后应用于xs
的新函数。
Since Haskell functions are curried , these are just two ways of looking at the exact same thing. 由于Haskell函数是curry ,这些只是看待完全相同的两种方式。
It might be helpful to define a couple type aliases, to make it a bit more explicit what all those arrows and brackets are doing: 定义一对类型别名可能会有所帮助,使其更加明确所有箭头和括号所做的事情:
type F1 a b = a -> b -- type synonym for single-argument functions
type List a = [a] -- type synonym for lists
so now you can write map
's type signature as: 所以你现在可以把
map
的类型签名写成:
map :: F1 s t -> List s -> List t
which, if you're more familiar with Java or C++ or whatever, looks syntactically a bit more like: 如果你对Java或C ++或其他什么更熟悉,那么在语法上看起来更像:
List<T> map(F1<S, T> fun, List<S> list); // applies fun to each element in list
So you can think of it this way: map
takes a function and a list, and returns another list. 所以你可以这样想:
map
接受一个函数和一个列表,然后返回另一个列表。 However, since functions are curried in Haskell, you don't have to pass all parameters at once. 然而,由于功能在Haskell 咖喱 ,你不必一次通过所有参数。 You could get away with partially applying
map
to just its first argument. 您可以将
map
部分应用于其第一个参数。 So really its type signature is more like: 所以它的类型签名更像是:
F1<List<S>, List<T>> map(F1<S, T> fun); // returns a function that applies fun to each element in a list
... which, when you call map
with just that one fun
argument, gives you something that sort of looks like: ...当你用一个
fun
参数调用map
时,会给你一些类似的东西:
List<T> mapFun(List<S> list); // applies fun to each element in list
So now back to Haskell: you can read map :: (s -> t) -> [s] -> [t]
either as: 现在回到Haskell:你可以读取
map :: (s -> t) -> [s] -> [t]
:
map
takes a function from s to t , and a list of s , and returns a list of t " map
从s到t获取一个函数,以及一个s列表,并返回一个t列表” map
takes a function from s to t , and turns it into a function from a list of s to a list of t " map
从s到t采用函数,并将其转换为从s 列表到t列表的函数 ” The former is fine; 前者很好; the latter is more helpful.
后者更有帮助。
How about "map is a function which maps a (function from s to t) over a (list of s) giving a (list of t)"? “map是一个函数,它将(从s到t的函数)映射到一个(s的列表)给出一个(t的列表)”? That is a direct translation of the type signature into English (albeit not very elegant English).
这是将类型签名直接翻译成英文(虽然不是很优雅的英文)。
Read the signature from the end: -> [t]
means returns a list of t
. 从最后读取签名:
-> [t]
表示返回t
列表 。 The rest is 'regular' parameters. 其余的是“常规”参数。
So, map
takes a function that from an s
makes a t
, and a list of s
. 因此,
map
采用s
生成t
的函数和s
的列表。
Now it's easy: take a function s->t
, apply it to each element of [s]
and the result of it is [t]
. 现在很容易:取一个函数
s->t
,将它应用于[s]
每个元素,结果为[t]
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.