Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell:初学者函数语法混乱_Haskell - Fatal编程技术网

Haskell:初学者函数语法混乱

Haskell:初学者函数语法混乱,haskell,Haskell,我目前正在尝试学习Haskell,但我正在努力理解语法。例如,以map函数为例: map :: (s -> t) -> [s] -> [t] map f [] = [] map f (x:xs) = f x : map f xs 我理解函数的作用,并且map有一个f::s->t函数作为参数。但是我把map:(s->t)->[s]->[t]理解为“map是一个函数,它将函数从s映射到t,然后映射到t”,这显然是错误的。有人能帮我澄清一下吗?map是一个函数,它将一个(函数从s映

我目前正在尝试学习Haskell,但我正在努力理解语法。例如,以
map
函数为例:

map :: (s -> t) -> [s] -> [t]
map f [] = []
map f (x:xs) = f x : map f xs
我理解函数的作用,并且
map
有一个
f::s->t
函数作为参数。但是我把map:(s->t)->[s]->[t]理解为“map是一个函数,它将函数从s映射到t,然后映射到t”,这显然是错误的。有人能帮我澄清一下吗?

map是一个函数,它将一个(函数从s映射到t)映射到一个(s列表)上,给出一个(t列表)”? 这是将类型签名直接翻译成英语(尽管不是很优雅的英语)。

类型
(s->t)->[s]->[t]
可以通过两种方式读取。一种方法是将其视为两个参数的函数,第一个参数是
s->t
类型的函数,第二个参数是
[s]
类型的列表。返回值的类型为
[t]

另一种方法是理解函数箭头是右关联的,因此类型相当于
(s->t)->([s]->[t])
。在这种解释下,
map
是一个函数,它将一个函数从一个元素转换到另一个元素
s->t
,并将其转换为一个函数从一个列表转换到另一个列表
[s]->[t]

类似地,在使用函数时,可以将
map foo xs
视为将函数
map
应用于两个参数
foo
xs
。或者,由于函数应用程序是左关联的,您可以将其视为
(map foo)xs
,将
map
应用于单个参数
foo
,以获取新函数,然后将其应用于
xs


因为Haskell函数是,所以这只是两种看待完全相同事物的方式。

从末尾读取签名:
->[t]
表示返回一个
t
的列表。其余是“常规”参数

因此,
map
接受一个函数,该函数从
s
生成一个
t
,以及一个
s
列表


现在很简单:取一个函数
s->t
,将其应用于
[s]
的每个元素,其结果就是
[t]
定义一对类型别名可能会有帮助,使所有这些箭头和括号的作用更加明确:

type F1 a b=a->b--单参数函数的类型同义词
类型列表a=[a]--列表的类型同义词
因此,现在您可以将
映射
的类型签名编写为:

map::F1 s t->List s->List t
<>,如果你更熟悉java或C++,或者任何语法,看起来语法上有点像:

列表地图(F1乐趣,列表);//将乐趣应用于列表中的每个元素
所以你可以这样想:
map
接受一个函数和一个列表,然后返回另一个列表。但是,由于函数是在Haskell中实现的,因此不必一次传递所有参数。您可以仅对其第一个参数部分应用
map
。所以它的类型签名更像:

F1地图(F1乐趣);//返回一个函数,该函数将乐趣应用于列表中的每个元素
。。。当你用一个
fun
参数调用
map
时,它会给你一些类似的东西:

List mapFun(列表);//将乐趣应用于列表中的每个元素
现在回到Haskell:您可以阅读
map::(s->t)->[s]->[t]
如下:

  • map
    获取一个从s到t的函数和一个s列表,并返回一个t列表
  • map
    将函数从s到t,并将其转换为从s列表到t列表的函数

前者是好的;后者更有用。

警告:如果您不熟悉Java或其他什么,最好完全忽略我的答案,除了最后一点;)同意。所有的“s”和“s”让我想到“都不,现在我理解了haskell..他们再次更改它和/或提出另一个扩展”:-)不够笼统;例如,您将如何翻译类型签名
zipWith:(a->b->c)->[a]->[b]->[c]
?术语“映射布拉赫之上布拉赫的函数”来源于您所知道的映射,而不是它的类型签名。对于
zipWith
示例,我认为它“将函数从a和b转换为c,并将其从a列表和b列表转换为c列表中的新函数。”