Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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:在函数合成中使用map_Haskell_Syntax_Map_Function Composition - Fatal编程技术网

Haskell:在函数合成中使用map

Haskell:在函数合成中使用map,haskell,syntax,map,function-composition,Haskell,Syntax,Map,Function Composition,我对Haskell比较陌生,所以如果我的问题听起来很愚蠢,我道歉。我一直试图理解函数组合是如何工作的,我遇到了一个问题,我想知道有人能帮我解决这个问题。在以下两种情况下,我在函数组合中使用map: map(*2)。过滤偶数[1,2,3,4] map(*2)。zipWith max[1,2][4,5] 尽管filter和zipWith函数都返回一个列表,但只有第一个组合有效,而第二个组合抛出以下错误: "Couldn't match expected type '[Int] -> [In

我对Haskell比较陌生,所以如果我的问题听起来很愚蠢,我道歉。我一直试图理解函数组合是如何工作的,我遇到了一个问题,我想知道有人能帮我解决这个问题。在以下两种情况下,我在函数组合中使用map:

  • map(*2)。过滤偶数[1,2,3,4]
  • map(*2)。zipWith max[1,2][4,5]
尽管filter和zipWith函数都返回一个列表,但只有第一个组合有效,而第二个组合抛出以下错误:

"Couldn't match expected type '[Int] -> [Int]' with actual type '[c0]'

任何建议都将不胜感激。

zipWith max[1,2][4,5]的结果是一个列表,而不是一个函数。(.)运算符需要一个函数作为其右操作数。因此,第二行出现了错误。也许你想要的是

map (*2) (zipWith max [1,2] [4,5])
您的第一个示例没有在WinHugs上编译(Hugs模式);它也有同样的错误。以下方法将起作用

(map (*2) . filter even) [1,2,3,4]
因为它由两个函数组成,并将结果函数应用于一个参数。

回想一下
(。
的类型

它接受三个参数:两个函数和一个初始值,并返回由这两个函数组成的结果

现在,函数对其参数的应用绑定比
(.)
运算符更紧密。 你的表情是:

map (*2) . filter even [1,2,3,4]
解析为:

(.) (map (*2)) (filter even [1,2,3,4])
现在,第一个参数,
map(*2)
可以了。它有类型
(b->c)
,其中
b
c
numa=>[a]
。但是,第二个参数是一个列表:

Prelude> :t filter even [1,2,3,4]
filter even [1,2,3,4] :: Integral a => [a]
因此,当
()
函数需要一个函数时,类型检查器会抱怨您将
[a]
作为参数传递

这就是我们看到的:

Couldn't match expected type `a0 -> [b0]' with actual type `[a1]'
In the return type of a call of `filter'
In the second argument of `(.)', namely `filter even [1, 2, 3, 4]'
In the expression: map (* 2) . filter even [1, 2, 3, 4]
所以。。。括号

使用
$
运算符添加括号:

map (*2) . filter even $ [1,2,3,4]
或者使用显式paren,删除两个函数的组合

map (*2) (filter even [1,2,3,4])
甚至:

(map (*2) . filter even) [1,2,3,4]

以下表格有效:

map (* 2) $ filter even [1, 2, 3, 4]
(map (* 2) . filter even) [1, 2, 3, 4]
map (* 2) $ zipWith max [1, 2] [4, 5]
(\xs -> map (* 2) . zipWith max xs) [1, 2] [4, 5]
但不包括以下内容:

map (* 2) . filter even [1, 2, 3, 4]
map (* 2) . zipWith max [1, 2] [4, 5]
(map (* 2) . zipWith max) [1, 2] [4, 5]
为什么会这样?嗯,举个例子

map (* 2) . zipWith max [1, 2] [4, 5]
这和

(map (* 2)) . (((zipWith max) [1, 2]) [4, 5])
(map(*2))
的类型为
[Int]->[Int]
(假设默认为
Int
),
((最大值为[1,2])[4,5])
的类型为
[Int]
的类型为
(b->c->(a->b)-->a->c
([Int]->[Int])->([Int]->[Int])->[Int]
在这种非多态的情况下,这是类型错误的。另一方面,在这种非多态情况下,
($)
具有类型
(a->b)->a->b
,或
([Int]->[Int])->[Int]->[Int]
,因此:

(map (* 2)) $ (((zipWith max) [1, 2]) [4, 5])

类型正确。

由于
()
的优先级较低,Haskell解析

map (*2) . filter even [1,2,3,4]
作为

i、 e.使用过滤偶数[1,2,3,4](一个列表)的结果编写
map(*2)
(一个函数),这毫无意义,是一个类型错误

您可以使用@Theodore的建议或使用
($)


如果您检查映射类型,它是:
(a->b)->[a]->[b]

因此,它将a的函数转换为b,然后是a的列表,并返回b的列表。对吧?

现在,您已经通过传递参数
(*2)
将a的函数提供给b。因此,部分应用的map函数最终是:
[Integer]->[Integer]
,这意味着您将收到一个整数列表并返回一个整数列表

到目前为止,您可以编写(.)一个具有相同签名的函数。如果您检查
过滤器的类型,甚至
,您会发现它是:
[Integer]->[Integer]
,因此这里的组合是有效的候选组合

如果您检查:
map(*2)的类型,则此组合不会改变函数的最终签名。过滤偶数
它是
[Integer]->[Integer]


map(*2)的情况并非如此。zipWith max[1,2][4,5]
因为
zipWith max
没有与
map(*2)
所期望的签名相同的签名,答案是否有帮助?(特别是)第一个实际生成的输出
无法将预期的类型a0->[b0]'与实际类型[a1]'匹配。
我知道OP专门询问函数的组成,但这个示例最适合直接
$
,即
映射(*2)$filter甚至[1,2,3,4]
map (*2) . filter even [1,2,3,4]
map (*2) . (filter even [1,2,3,4])
map (*2) . filter even $ [1,2,3,4]