【发布时间】:2016-07-06 07:02:21
【问题描述】:
我想了解如何在无点中完成以下操作:
withinBounds :: [Int] -> Bool
withinBounds xs = (all (>= 0) xs) && (all (<= 8) xs)
我知道为了可读性/理智起见以这种方式编写它会更好,但我想了解更多关于如何编写函数的信息。我一直在摸索如何做到这一点。 整个(扩展?)类型签名是
[Int] -> ([Int] -> Bool) -> ([Int] -> Bool) -> (Bool -> Bool -> Bool) -> Bool
我想要得到的组合的类型签名是
(a -> b) -> (a -> c) -> (b -> c -> d) -> (a -> d)
我以混蛋-lambda 形式写了以下注释。如果有办法在某种程度上简化 lambda 演算的问题,如果也能解释一下就太好了:
\L@[] -> \f1@([] -> Bool) -> \f2@([] -> Bool) -> \f3@(Bool -> Bool -> Bool) -> f3.(f1.L).(f2.L)
在上面,. 是应用程序,@ 是捕获(所以 f3 是 (Bool -> Bool -> Bool) 的另一个名称)。
非常感谢。
编辑:我知道这不是最优化或可重用的代码,而且我知道把它变成无点会使它在可读性等方面变得更糟。为了澄清,我问我如何才能把它变成无点因为我想了解有关 haskell 和组合的更多信息。
【问题讨论】:
-
您的
withinBounds不可组合,最好编写单个元素的检查,然后调用all。事实上,我可能只是内联all withinBounds其中 withinBounds 用于单个元素。 -
谢谢。是否有迹象表明该功能不可组合? (例如,在正文中的多个位置都需要输入?)
-
@MIJOTHY:通常,如果类型更通用,它可能更可重用,例如
withinBounds :: Ord e => (e, e) -> e -> Bool; withinBounds (a,b) x = a <= x && x <= b。现在你原来的函数就是all (withinBounds (0,8))。此外,我可以将其用作过滤器的谓词:filter (withinBounds (4,100)) [1..103]。 -
是的,我可以理解通用 = 更可重用,但我想知道是否有某种方法可以判断函数是否可以用无点(使用组合运算符)编写。也许我对“可组合”的使用是错误的。所以用你写的更通用的版本来重新表述这个问题,我可以写
withinBounds (a,b) x = a <= x && x <= bin point-free吗? -
@MIJOTHY:哦,对不起,我忘了告诉你。 Hackage 上有
pointfree包,#haskell上有 lambdabot,pointfree.io 上有。话虽如此,我通常会移动参数,直到最终得到一个 eta 可约函数,例如stackoverflow.com/a/36542287/1139697.
标签: haskell lambda function-composition pointfree