我刚开始在大学学习Haskell,在玩弄它时,我偶然发现了一个我似乎无法掌握的问题。 以下代码为我提供了所需的结果:
import Data.List
list = ["Hello", "world"]
main = print $ intercalate " something " (reverse (map reverse list))
输出:
"dlrow something olleH"
但我想用点而不是括号来编写'main'函数,所以尝试了:
main = print $ intercalate " something " . reverse . map reverse list
然而,这给了我以下错误:
test.hs:5:54: error:
• Couldn't match expected type ‘a0 -> [[Char]]’
with actual type ‘[[Char]]’
• Possible cause: ‘map’ is applied to too many arguments
我认为这些点与括号完全相同:功能组合。为什么括号有效,而圆点给我一个类型相关的错误?任何帮助将不胜感激!
答案 0 :(得分:3)
功能组成的等价如下:
main = (print . intercalate " something " . reverse . map reverse) list
main = print . intercalate " something " . reverse . map reverse $ list
或删掉不必要的括号:
map reverse list
在您的尝试中,.
是一个单独的表达式,即中缀map reverse
运算符的参数,它不起作用 - 您只能编写list
函数,并且然后将整个组合函数应用于$userdata = array(
'email' => Input::get('email'),
'password' => Input::get('password')
);
if (Auth::attempt($userdata)) {
return view('dashboard');
}
参数。
答案 1 :(得分:3)
括号不代表功能构成。它们只是意味着“将这个子表达式组合”。当然,您可以使用来创建一系列函数组合:以下将c
定义为函数f
,g
和{{1}的组合}}
h
这也可以写成:
c x = f (g (h x))
因此,你可以写
c = f . g . h
但是如果你再次内联main = print $ c list
where c = intercalate " something " . reverse . map reverse
,你需要注意不要弄乱解析规则:只是在该组合链的右边写c
不会,因为函数应用程序绑定比任何中缀运算符更紧密(包括list
,尽管这实际上是最严格的中缀运算符)。即,
.
实际上被解析为
intercalate " something " . reverse . map reverse list
但这不是你想要的。你需要确保(intercalate " something ") . (reverse) . (map reverse list)
实际上是整个组合链的参数,而不仅仅是它的最后一个元素;执行此操作的首选方法是使用list
运算符:
$
intercalate " something " . reverse . map reverse $ list
具有最低预设值,因此将其解析为
$
或者,您可以立即将((intercalate " something ") . (reverse) . (map reverse)) (list)
应用于map reverse
- 这本身并没有错,只是结果不再是合成链的一部分:
list
答案 2 :(得分:2)
使用.
的函数组合意味着该函数将有另一个参数。如果您改为编写以下内容,那就可以了。
main = print $ (intercalate " something " . reverse . map reverse) list
这样,list
值是括号内组成的函数的参数。