混乱钻营和点自由风格在Haskell

我想实现的功能

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

这是对这个问题的话题。 我试图做到这一点没有明确的递归。 我想出了下面的代码

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

因为它不是懒惰的(这是需要在这个问题)我的功能没有工作,所以没有upvotes有:-)。

但是,我并没有就此停止。 我试图使功能-免费的,所以 ,这将是短(甚至冷却器)。 由于参数fxs是最后的在我刚刚把他们的表达:

every = liftM (all id) $ sequence $ map

但由于预计没有工作,其实它并没有在所有的工作:

[1 1]编译主(stk.hs,解释)stk.hs:53:42:无法满足预期的类型`[马]“对推断类型'(A1 - > B) - > [A1] - > [B]“在'($),第二个参数',也就是'绘制'在'($),第二个参数',即'序列$图'在表达式:liftM(所有ID)$序列$地图失败,模块加载:无。

这是为什么? 我的印象是,这是可以简单地砸尾随函数参数,这基本上就是钻营即将。

--------------解决方案-------------

$ a的定义

f $ x = fx

让我们完全括起的作用:

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

和你的咖喱版本:

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

当你注意到了,这些都是不相同的。 您只能删除尾随函数参数的时候都适用的最后一件事。 例如,

fx = gcx

其实

fx = (gc) x

和(GC)应用到x放在最后,所以你可以写

f = gc

一个图案与应用程序运营商$是它往往成为组合物操作者。 在点免费版本。 这是因为

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

而这正是我们需要尽一切完全分免费电话:

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

可悲的是,由于在Haskell的类型系统的限制,这其中需要一个明确的类型签名:

every :: (Monad m) => (a -> m Bool) -> [a] -> m Bool

分类:哈斯克尔 时间:2015-03-15 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.843 (s). 10 q(s)