waj*_*eeh 5 syntax haskell map function-composition
我对Haskell相对较新,如果我的问题听起来很愚蠢,那么道歉.我一直试图理解功能组合是如何工作的,我遇到了一个问题,我想知道有人可以帮助我.我在以下两个场景中使用函数组合中的map:
map (*2) . filter even [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]'
Run Code Online (Sandbox Code Playgroud)
任何建议将不胜感激.
Don*_*art 17
回想一下这种类型(.).
(.) :: (b -> c) -> (a -> b) -> a -> c
Run Code Online (Sandbox Code Playgroud)
它有三个参数:两个函数和一个初始值,并返回组成的两个函数的结果.
现在,函数对其参数的应用比(.)运算符更紧密.所以你的表达:
map (*2) . filter even [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)
被解析为:
(.) (map (*2)) (filter even [1,2,3,4])
Run Code Online (Sandbox Code Playgroud)
现在,第一个参数,没问题map (*2).它有型(b -> c),其中b和c是Num a => [a].但是,第二个参数是单个列表:
Prelude> :t filter even [1,2,3,4]
filter even [1,2,3,4] :: Integral a => [a]
Run Code Online (Sandbox Code Playgroud)
所以类型检查器会抱怨你在函数需要函数[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]
Run Code Online (Sandbox Code Playgroud)
所以......括号!
使用$运算符添加括号:
map (*2) . filter even $ [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)
或使用明确的parens,删除两个函数的组合
map (*2) (filter even [1,2,3,4])
Run Code Online (Sandbox Code Playgroud)
甚至:
(map (*2) . filter even) [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)
结果zipWith max [1,2] [4,5]是列表,而不是函数.(.)运算符需要一个函数作为其右操作数.因此你的第二行错误.可能你想要的是什么
map (*2) (zipWith max [1,2] [4,5])
Run Code Online (Sandbox Code Playgroud)
你的第一个例子不能在WinHugs上编译(拥抱模式); 它有同样的错误.以下将有效
(map (*2) . filter even) [1,2,3,4]
Run Code Online (Sandbox Code Playgroud)
因为它组成了两个函数并将结果函数应用于参数.
以下表格有效:
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]
Run Code Online (Sandbox Code Playgroud)
但不是以下内容:
map (* 2) . filter even [1, 2, 3, 4]
map (* 2) . zipWith max [1, 2] [4, 5]
(map (* 2) . zipWith max) [1, 2] [4, 5]
Run Code Online (Sandbox Code Playgroud)
为什么会这样?好吧,举个例子
map (* 2) . zipWith max [1, 2] [4, 5]
Run Code Online (Sandbox Code Playgroud)
它是一样的
(map (* 2)) . (((zipWith max) [1, 2]) [4, 5])
Run Code Online (Sandbox Code Playgroud)
(map (* 2))有类型[Int] -> [Int](假设是默认的Int),(((zipWith max) [1, 2]) [4, 5])有类型[Int]和(.)类型(b -> c) -> (a -> b) -> a -> c或([Int] -> [Int]) -> ([Int] -> [Int]) -> [Int] -> [Int]在这种非多态的情况下,所以这是错误的类型.另一方面($)有类型(a -> b) -> a -> b,或者([Int] -> [Int]) -> [Int] -> [Int]在这种非多态的情况下,所以这个:
(map (* 2)) $ (((zipWith max) [1, 2]) [4, 5])
Run Code Online (Sandbox Code Playgroud)
打字很好.
| 归档时间: |
|
| 查看次数: |
2697 次 |
| 最近记录: |