[英]Make “A || B && C” point-free in Haskell
I'm tackling a simple leap year exercise in Haskell, and I'd like to make my solution point-free.我正在 Haskell 中处理一个简单的闰年练习,我想让我的解决方案无点。 Starting from this:从此开始:
isLeapYear :: Integer -> Bool
isLeapYear year = divisibleBy 400 year || divisibleBy 4 year && not (divisibleBy 100 year)
where
divisibleBy m y = (== 0) $ flip mod m y
I tried using liftA3
, with a function doing (x || (y && z))
following this , but the tests do not finish and I don't know why.我试着用liftA3
,具有功能做(x || (y && z))
下面这个,但测试没有完成,我不知道为什么。
So, then, I have 3 questions:那么,我有3个问题:
divisibleBy
to be point-free?在我的第一个解决方案中,是什么阻止了divisibleBy
成为无点? (Typechecker complains if I remove the arguments) (如果我删除参数,类型检查器会抱怨)liftA3 (\\xyz -> x || (y && z)) (divisibleBy 400) (divisibleBy 4) (indivisibleBy 100)
, but the tests hang.正如我之前提到的,我尝试了类似liftA3 (\\xyz -> x || (y && z)) (divisibleBy 400) (divisibleBy 4) (indivisibleBy 100)
,但测试挂起。 Why does that happen?为什么会这样? I'm not getting how liftA3
works.我不liftA3
是如何工作的。Thanks a lot for your help.非常感谢你的帮助。
In my first solution, what's preventing divisibleBy to be point-free?在我的第一个解决方案中,是什么阻止了 divisibleBy 成为无点? (Typechecker complains if I remove the arguments) (如果我删除参数,类型检查器会抱怨)
You might think that these are equivalent (I am writing flipmod
as one function for simplicity's sake):您可能认为这些是等效的(为了简单起见,我将flipmod
作为一个函数编写):
divisibleBy m y = (== 0) $ flipmod m y
divisibleBy' = (== 0) . flipmod
But in actuality, divisibleBy'
is now an (invalid) function that takes an argument x
and then compares flipmod x
to zero:但实际上, divisibleBy'
现在是一个(无效的)函数,它接受一个参数x
然后将flipmod x
与零进行比较:
((==0) . flipmod) 5
→ (==0) (flipmod 5)
→ flipmod 5 == 0
Comparing a function ( flipmod 5
) and a number is certainly no good.比较一个函数( flipmod 5
)和一个数字肯定不好。
You'd need to write something more sophisticated, namely:你需要写一些更复杂的东西,即:
divisibleBy = ((== 0) .) . flipmod
So that now, properly:所以现在,正确地:
divisibleBy 5 6
→ (((== 0) .) (flipmod 5)) 6
→ ((== 0) . flipmod 5) 6
→ (== 0) (flipmod 5 6)
→ flipmod 5 6 == 0
This construction (f.).g
can also be written as ((.).(.)) fg
, and that operator is sometimes called dot
.这种构造(f.).g
也可以写成((.).(.)) fg
,并且该运算符有时称为dot
。 I don't think writing things like this is a very good idea, but it might answer your question.我不认为写这样的东西是一个很好的主意,但它可能会回答你的问题。
The tests hang.测试挂起。 Why does that happen?为什么会这样?
I don't know.我不知道。 You'll probably need to provide an mcve here, because this works fine for me as a full program:你可能需要在这里提供一个mcve ,因为这对我来说是一个完整的程序:
import Control.Applicative
isLeapYear :: Integer -> Bool
isLeapYear = liftA3 (\x y z -> x || (y && z))
(divisibleBy 400)
(divisibleBy 4)
(not . divisibleBy 100)
where
divisibleBy m y = (== 0) $ flip mod m y
main = print (filter isLeapYear [1850..1950])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.