HASKELL Лямбда-выражение '\ xs -> ...' имеет один аргумент, но его тип '[t]' не имеет ни одного - PullRequest
1 голос
/ 25 января 2020

Нам пришлось написать лямбда-функцию в Haskell, но она всегда показывает ошибки. Что я делаю не так? все коды имеют одинаковые ошибки, но я не понимаю, как их исправить.

length' :: [a] -> [a] -> Int 
length' [] = 0
length' (x:xs) (y:ys) = \n -> if length (x:xs) > (y:ys) then 1 else if (x:xs) == (y:ys) then 0 else if (x:xs) < (y:ys) then -1

find :: a -> [a] -> Bool
find p [] = False
find p xs = \p -> if p `elem` xs then True else False

remove y [] = []
remove y (x:xs) = \xs -> if y == x then xs else x: remove y xs 


• Couldn't match expected type ‘Bool’ with actual type ‘a -> Bool’
• The lambda expression ‘\ p -> ...’ has one argument,
  but its type ‘Bool’ has none
  In the expression: \ p -> if p `elem` xs then True else False
  In an equation for ‘find’:
      find p xs = \ p -> if p `elem` xs then True else False

ошибки одинаковы

Couldn't match expected type ‘[t]’ with actual type ‘[t] -> [t]’
    • The lambda expression ‘\ xs -> ...’ has one argument,
      but its type ‘[t]’ has none
      In the expression: \ xs -> if y == x then xs else x : remove y xs
      In an equation for ‘remove’:

Ответы [ 2 ]

12 голосов
/ 25 января 2020

У вас есть проблема с этой функцией:

find :: a -> [a] -> Bool
find p [] = False
find p xs = \p -> if p `elem` xs then True else False

При объявлении типа она принимает значение типа a, список значений, а также все типы a, и возвращает Bool.

В случае find, который соответствует p и xs, компилятор должен принять объявление типа, поэтому p должен иметь тип a и xs должен иметь тип [a]. Это означает, что возвращаемое значение должно быть Bool.

Однако выражение возвращает лямбда-выражение. Это конкретное лямбда-выражение имеет тип Eq a => a -> Bool. Вы можете попробовать это в GHCi:

Prelude> xs = undefined :: [a]
Prelude> :t \p -> if p `elem` xs then True else False
\p -> if p `elem` xs then True else False :: Eq a => a -> Bool

Вы можете решить эту проблему, не , возвращая функцию, то есть не возвращая лямбда-выражение.

6 голосов
/ 25 января 2020

К сожалению, есть много ошибок: я укажу только первые.

length' :: [a] -> [a] -> Int 

Это означает, что length' принимает два аргумента типа [a] и возвращает Int. Это странно: почему функция длины берет два списков? Давайте предположим, что два аргумента - это действительно то, что вам нужно, и двигайтесь дальше.

length' [] = 0

Здесь вы определяете length' с одним аргументом []. Почему не два?

length' (x:xs) (y:ys) = \n -> ...

Здесь вы определяете длину, имея два аргумента, x:xs и y:xs. Однако вы возвращаете функцию \n -> ..., которая не соответствует типу возврата Int.

Более того:

length (x:xs) > (y:ys)

выше, вы сравниваете Int и список. Скажем, 5 < [1,2,3] верно? Нет, это бессмысленное сравнение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...