10

I was trying to implement the function

every :: (a -> IO Bool) -> [a] -> IO Bool 

which was the topic for this question. I tried to do this without explicit recursion. I came up with the following code

every f xs = liftM (all id) $ sequence $ map f xs

My function didn't work since it wasn't lazy (which was required in the question), so no upvotes there :-).

However, I did not stop there. I tried to make the function point-free so that it would be shorter (and perhaps even cooler). Since the arguments f and xs are the last ones in the expression I just dropped them:

every = liftM (all id) $ sequence $ map 

But this did not work as expected, in fact it didn't work at all:

    [1 of 1] Compiling Main             ( stk.hs, interpreted )

    stk.hs:53:42:
        Couldn't match expected type `[m a]'
               against inferred type `(a1 -> b) -> [a1] -> [b]'
        In the second argument of `($)', namely `map'
        In the second argument of `($)', namely `sequence $ map'
        In the expression: liftM (all id) $ sequence $ map
    Failed, modules loaded: none.

Why is that? I was under the impression that it was possible to simply drop trailing function arguments, which basically is what currying is about.

4

1 回答 1

25

$的定义是

f $ x = f x

让我们把你的函数完全括起来:

every f xs = (liftM (all id)) (sequence ((map f) xs))

和你的咖喱版本:

every = (liftM (all id)) (sequence map)

正如您所注意到的,这些并不相同。您只能在最后应用尾随函数参数时删除它们。例如,

f x = g c x

实际上是

f x = (g c) x

并且 (gc) 对 x 的应用是最后的,所以你可以写

f = g c

应用程序运算符 $ 的一种模式是它经常成为组合运算符。无积分版本。这是因为

f $ g $ x

相当于

(f . g) $ x

例如,

every f xs = liftM (all id) $ sequence $ map f xs

可以变成

every f xs = (liftM (all id) . sequence . map f) xs

此时您可以删除 xs:

every f = liftM (all id) . sequence . map f

消除参数 f 更加困难,因为它是在组合运算符之前应用的。让我们使用来自http://www.haskell.org/haskellwiki/Pointfree的点的定义:

dot = ((.) . (.))

有了积分,这是

(f `dot` g) x = f . g x

并且正是我们需要使每一个完全免费的点:

every = (liftM (all id) . sequence) `dot` map

遗憾的是,由于 Haskell 类型系统的限制,这需要一个明确的类型签名:

every :: (Monad m) => (a -> m Bool) -> [a] -> m Bool
于 2009-05-25T17:15:49.277 回答