2016-03-18 4 views
1

Следующая функция принимает два списка возвращает все элементы, которые встречаются в обоих списках на одних и тех же показателей:

equal_els :: Eq a => [a] -> [a] -> [a] 
equal_els xs ys = map fst $ filter (uncurry (==)) $ zip xs ys 

Видя, как xs ys происходит в конце с обеих сторон, я сделал что я всегда делаю в этом случае: удалите его! Тем не менее, в результате

equal_els = map fst $ filter (uncurry (==)) $ zip 

не компилируется больше, и я не могу за жизнь мне понять, что сообщение об ошибке пытается сказать мне!


Couldn't match expected type ‘[a] -> [a] -> [a]’ 
      with actual type ‘[b0]’ 
Relevant bindings include 
    equal_els :: [a] -> [a] -> [a] (bound at ...) 
In the expression: map fst $ filter (uncurry (==)) $ zip 
In an equation for ‘equal_els’: 
    equal_els = map fst $ filter (uncurry (==)) $ zip 

Couldn't match expected type ‘[(b0, b0)]’ 
      with actual type ‘[a0] -> [b1] -> [(a0, b1)]’ 
Probable cause: ‘zip’ is applied to too few arguments 
In the second argument of ‘($)’, namely ‘zip’ 
In the second argument of ‘($)’, namely 
    ‘filter (uncurry (==)) $ zip’ 
+1

: «' zip' применяется к слишком малым аргументам »-' zip' теперь '' [a] -> ([b] -> [(a, b)]) 'и это пузыри - просто позвольте 'xs' стоять и будет работать' equal_els xs = ... $ zip xs' – Carsten

ответ

2

Тип $ является (a -> b) -> a -> b, так что она принимает функцию и аргумент, а затем передает аргумент функции.

Вы пытаетесь передать zip в качестве параметра, однако вы должны передать результат функции zip, т. Е. Объединить две функции. Это цель . (функция состава):

Prelude> :t (.) 
(.) :: (b -> c) -> (a -> b) -> a -> c 

Prelude> let equal_els xs = map fst . filter (uncurry (==)) . zip xs 
Prelude> equal_els [1, 2, 3] [1, 4, 3] 
[1,3] 

Однако, в результате чего последний элемент делает эту функцию нечитаемым:

Prelude> let equal_els xs =  map fst . filter (uncurry (==)) . zip xs 
Prelude> let equal_els xs = (.) (map fst . filter (uncurry (==))) (zip xs) 
Prelude> let equal_els xs = ((.) (map fst . filter (uncurry (==)))) . zip $ xs 
Prelude> let equal_els = ((.) (map fst . filter (uncurry (==)))) . zip 

Так что, я бы оставить эту функцию с одним параметром.

+0

Ах, я понимаю! Спасибо – fabian789

+0

@ fabian789 Рад, что это помогло :) – soon

Смежные вопросы