我想要实现的功能

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

这是主题 这个问题.我试图做这个 没有明确的递归.我想出了下列代码

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

我的功能没有运作,因为它不是懒惰的(这是需要在该问题),所以没有"顶"有:-).

然而,我并没有停止。我试图让的功能 点免费的 因此,它将更短(甚至冷却机)。由于参数 fxs 是最后表达我刚把他们:

every = liftM (all id) $ sequence $ map 

但是,这并没有预期的工作,事实上它并没有在所有的工作:

    [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.

为什么?我的印象是,它是可以简单地拖追踪功能的参数,这基本上是什么样的扩充。

有帮助吗?

解决方案

的$定义是

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

和(g C)到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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top