gpt4 book ai didi

haskell - 模式守卫和让

转载 作者:行者123 更新时间:2023-12-02 08:15:42 24 4
gpt4 key购买 nike

在完成项目 euler 的前几个练习时,我对 haskell 在 do 表示法中处理失败的 let 绑定(bind)的方式感到惊讶。
我打算做相当于:

sundays = length $ do
year <- [1901..2000]
month <- [1..12]
(_, _, 7) <- return . toWeekDate $ fromGregorian year month 1
return ()

即查询某个时间范围内每月的第一天有多少天是星期日。这行得通,并且使用大小写绑定(bind)也可以。看起来它应该做同样的事情的 let 绑定(bind)总是通过,但是:

sundays = length $ do
year <- [1901..2000]
month <- [1..12]
let (_, _, 7) = toWeekDate $ fromGregorian year month 1
return ()

是什么导致了这种行为?

最佳答案

第二个示例中的 let 绑定(bind)永远不会被评估,因为它的值从未被使用过。这和写一样:

sundays = length $ do
year <- [1901..2000]
month <- [1..12]
return ()

如果您想扩展第二个示例,我建议您使用 guard来自 Control.Monad,它将按预期有效地过滤结果:

sundays2 = length $ do
year <- [1901..2000]
month <- [1..12]
let (_, _, day) = toWeekDate $ fromGregorian year month 1
guard $ day == 7
return ()

guard 是在列表理解的幕后使用的。您上面的代码可以像这样以列表理解形式编写:

sundays3 = length $ [ () | year <- [1901..2000]
, month <- [1..12]
, let (_, _, day) = toWeekDate $ fromGregorian year month 1
, day == 7 ]

关于haskell - 模式守卫和让,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42208385/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com