简单的Haskell编译错误不明白

时间:2012-02-03 20:25:48

标签: haskell compiler-errors ghc

我正在学习Haskell。我正在尝试编写一个函数,给定两个n个不同元素的列表,如果一个是另一个的排列,则返回true。我这样做是为了练习。

我首先把它写成:

isPermut :: (Eq a)=>[a]->[a]->Bool
isPermut u v = foldl (\acc x -> acc && (elem x u)) True v

这似乎有效。我现在尝试在没有lambda表达式的情况下重写它。所以我试试:

isPermut :: (Eq a)=>[a]->[a]->Bool
isPermut u v = foldl (&& (flip $ elem u)) True v

这给了我一个编译错误:

Couldn't match expected type `b0 -> Bool' with actual type `Bool'
Expected type: Bool -> b0 -> Bool
  Actual type: Bool -> Bool
In the first argument of `foldl', namely `(&& (flip $ elem u))'
In the expression: foldl (&& (flip $ elem u)) True v

这个错误是什么意思?在没有lambda的情况下编写函数的正确方法是什么? 感谢。

2 个答案:

答案 0 :(得分:7)

Folds必须使用两个参数的函数。您提供了一个参数的函数,因为(&& whatever)\ x -> x && whatever相同。

为了不在这里使用lambda,你需要一些方法来构造&&,一个双参数函数,(`elem` u),一个参数函数。 (请注意,(`elem` u)(flip elem) u\ x -> elem x u相同。)

答案 1 :(得分:7)

让我们一步一步。

\acc x -> acc && (elem x u)
= { write (&&) in prefix form }
\acc x -> (&&) acc (elem x u)
= { definition of flip }
\acc x -> (&&) acc (flip elem u x)
= { definition of (.) }
\acc x -> ((&&) acc . flip elem u) x
= { eta reduction }
\acc -> (&&) acc . flip elem u
= { write (.) in prefix form }
\acc -> (.) ((&&) acc) (flip elem u)
= { definition of flip }
\acc -> flip (.) (flip elem u) ((&&) acc)
= { definition of (.) }
\acc -> (flip (.) (flip elem u) . (&&)) acc
= { eta reduction }
flip (.) (flip elem u) . (&&)
= { syntax sugar for sections }
(. flip elem u) . (&&)