如何解决在Haskell中使“ A || B && C”无意义
我正在Haskell进行一次简单的leap年练习,我想使我的解决方案毫无意义。从这里开始:
isLeapYear :: Integer -> Bool
isLeapYear year = divisibleBy 400 year || divisibleBy 4 year && not (divisibleBy 100 year)
where
divisibleBy m y = (== 0) $ flip mod m y
我尝试使用liftA3
,并在this之后使用了(x || (y && z))
的函数,但是测试没有完成,我也不知道为什么。
那么,我有3个问题:
- 您对我如何实现这一目标有任何指示吗?
- 在我的第一个解决方案中,是什么导致
divisibleBy
毫无意义? (如果我删除参数,Typechecker会抱怨) - 如前所述,我尝试了类似
liftA3 (\x y z -> x || (y && z)) (divisibleBy 400) (divisibleBy 4) (indivisibleBy 100)
的方法,但是测试挂起了。为什么会这样呢?我不了解liftA3
的工作方式。
非常感谢您的帮助。
解决方法
在我的第一个解决方案中,是什么阻止了divisibleBy成为无分值? (如果我删除参数,Typechecker会抱怨)
您可能会认为它们是等效的(为简单起见,我将flipmod
作为一个函数编写):
divisibleBy m y = (== 0) $ flipmod m y
divisibleBy' = (== 0) . flipmod
但是实际上,divisibleBy'
现在是一个(无效)函数,该函数接受参数x
,然后将flipmod x
与零进行比较:
((==0) . flipmod) 5
→ (==0) (flipmod 5)
→ flipmod 5 == 0
比较一个函数(flipmod 5
)和一个数字肯定不好。
您需要编写更复杂的内容,即:
divisibleBy = ((== 0) .) . flipmod
因此,现在,正确地:
divisibleBy 5 6
→ (((== 0) .) (flipmod 5)) 6
→ ((== 0) . flipmod 5) 6
→ (== 0) (flipmod 5 6)
→ flipmod 5 6 == 0
此构造(f.).g
也可以写为((.).(.)) f g
,该运算符有时称为dot
。我认为写这样的事情不是一个好主意,但它可能会回答您的问题。
测试挂起。为什么会发生这种情况?
我不知道。您可能需要在此处提供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])
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。