我应该如何使用函数组合在Haskell中定义或编写我的函数?

时间:2015-06-22 20:52:33

标签: function haskell composition pointfree

我在Haskell中定义了一个函数,它应该是方形,然后在给定列表中的所有数字上加1。我想用函数组合编写该函数但不幸的是它不适用于dot beetwen函数但是它有效当我用括号编写我的函数时。我不明白为什么它不适用于dot或者更确切地说它不适用于函数组合?

square :: Int -> Int
square x = x * x

funSqr :: [Int] -> [Int]
funSqr xs = [(square x) | x <- xs]

funAdd1 :: [Int] -> [Int]
funAdd1 xs = [(x + 1) | x <- xs]

funFoldr :: [Int] -> Int 
funFoldr [] = 0
funFoldr (x:xs) = x + (funFoldr xs)

fun :: [Int] -> Int
fun xs = funFoldr(funAdd1(funSqr xs))

但是

fun :: [Int] -> Int
fun xs = funFoldr.funAdd1.funSqr xs  --Why on earth doesn't it work ?
fun xs = funFoldr.funRek xs        --or rather this way?

有人能照亮我的道路吗?

非常感谢 阿塞纳

1 个答案:

答案 0 :(得分:6)

Haskell解析规则101:函数应用程序比任何中缀运算符绑定得更紧密。空白量无关紧要。所以

funFoldr.funAdd1.funSqr xs
   ≡ funFoldr . funAdd1 . funSqr xs
   ≡ funFoldr . funAdd1 . (funSqr xs)

现在,funSqr xs不再是一个函数(只是将函数应用于xs结果)。你不能撰写不起作用的东西。

你打算尝试的是这个,确实有效:

(funFoldr.funAdd1.funSqr) xs

更常见的是,这是写的

funFoldr . funAdd1 . funSqr $ xs

funFoldr . funAdd1 $ funSqr xs

另外,如果您不提及funSqr xs,则可以避免xs分组:

fun :: [Int] -> Int
fun = funFoldr . funAdd1 . funSqr

这称为无点样式