gpt4 book ai didi

haskell - 使用 foldr 和 bind 终止任何内容

转载 作者:行者123 更新时间:2023-12-04 18:18:29 24 4
gpt4 key购买 nike

所以,基本上我有一些单子(monad)函数包裹在 MaybeT 中。我想使用 Nothing作为递归的终止情况

我对 foldr 的理解是如果它可以在不消耗整个列表的情况下产生结果,那么它可以安全地用于无限列表,即 foldr (&&) True $ repeat False仍然可以返回 False .

目前我有:

repeaterM a f = foldr (=<<) (return a) $ repeat f

这种类型检查,但实际上不起作用。谁能向我解释为什么我不能使用这个函数重复地将一个函数应用于它自己的结果,直到它返回 Nothing ?

最佳答案

foldr            :: (a -> b -> b) -> b -> [a] -> b
foldr k z = go
where
go [] = z
go (y:ys) = y `k` go ys

所以
foldr (&&) True $ repeat False
= go (repeat False) where go [] = True ; go (y:ys) = y && go ys
= False && go (repeat False) where go [] = True ; go (y:ys) = y && go ys
= False

如你所料。


foldr (=<<) (return a) $ repeat f
= go (repeat f) where go [] = return a ; go (y:ys) = y =<< ys
= f =<< go (repeat f) where go [] = return a ; go (y:ys) = y =<< ys
= f =<< f =<< go (repeat f) where go [] = return a ; go (y:ys) = y =<< ys
= f =<< f =<< f =<< go (repeat f) where go [] = return a ; go (y:ys) = y =<< ys
...

你在这里所做的并不是重复地将一个函数应用于它自己的结果,直到它返回 Nothing .

您正在从头开始构建计算:每个 =<< 的 RHS必须在执行 LHS 之前计算。但是你有一个无限的列表,所以你永远不会开始计算。

您可以尝试定义
repeaterM a f = foldl (>>=) (return a) $ repeat f

反而。这也不起作用(感谢 is7s)。

关于haskell - 使用 foldr 和 bind 终止任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11218436/

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