关于将函数与$和zip组合的困惑

时间:2016-03-18 17:00:50

标签: haskell

以下函数采用两个列表返回在相同索引的两个列表中出现的所有元素:

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 个答案:

答案 0 :(得分: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

所以,我将使用一个参数保留该函数。