Простая ошибка компиляции на Haskell не понята - PullRequest
2 голосов
/ 04 февраля 2012

В настоящее время я изучаю Haskell.Я пытаюсь написать функцию, которая дает два списка из n различных элементов, возвращает true, если один является перестановкой другого.Я делаю это как упражнение.

Я впервые написал это как:

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

Кажется, это работает.Я сейчас пытаюсь переписать его без лямбда-выражения.Поэтому я пытаюсь:

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

Что означает эта ошибка?Как правильно написать функцию без лямбды?Спасибо.

Ответы [ 2 ]

7 голосов
/ 04 февраля 2012

Давайте сделаем это по одному шагу за раз.

\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) . (&&)
7 голосов
/ 04 февраля 2012

Складки должны принимать функцию из двух аргументов.Вы дали функцию аргумента one , поскольку (&& whatever) совпадает с \ x -> x && whatever.

Чтобы здесь не использовать лямбду, вам нужен способ составить &&, два-аргументная функция, с (`elem` u), функция с одним аргументом.(Обратите внимание, что (`elem` u) совпадает с (flip elem) u или \ x -> elem x u.)

...