gpt4 book ai didi

haskell - 在 Haskell 中展开左 Binder

转载 作者:行者123 更新时间:2023-12-02 10:27:56 25 4
gpt4 key购买 nike

我正在尝试理解 Haskell 中的 monad,所以我正在阅读 https://wiki.haskell.org/All_About_Monads

让我们考虑上面站点中的一段代码:

maternalGrandfather :: Sheep -> Maybe Sheep
maternalGrandfather s = (return s) >>= mother >>= father

fathersMaternalGrandmother :: Sheep -> Maybe Sheep
fathersMaternalGrandmother s = (return s) >>= father >>= mother >>= mother

一切都清楚了。但我想知道如何制作一个长(也许是无限)序列。我的意思是例如:

expand :: Int -> Sheep -> MaybeSheep

例如,扩展 expand 10 s 使 (return s) >>=father >>=father >>=father >>=father >>=father .. ( 10次)

如何实现。也许使用递归进行扩展,但我无法想象停止时可以返回什么。

最佳答案

我们不要考虑如何将“一元函数”重复应用于一元值,而是考虑如何将一元函数列表“折叠”为单个函数,以便稍后应用于该一元值。

在 Haskell 中,“折叠”列出的原型(prototype)组合器称为 foldr :

foldr :: (a -> b -> b) -> b -> [a] -> b

foldr接收一个函数、一个初始值和一个列表作为参数。它的作用是替换每个构造函数 :包含函数的列表和空构造函数 []位于列表末尾并带有初始值。例如,考虑以下整数列表:

4 : 5 : 77 : 34 : []

假设我们要将列表的所有元素添加到88。我们可以这样做

foldr (+) 88 (4 : 5 : 77 : 34 : [])

这实际上等于

4 + 5 + 77 + 34 + 88.

好吧,现在假设列表的元素是 a -> a 类型的函数。我们可以使用复合运算符 (.) 将两个函数组合起来但是,我们应该用什么函数替换列表的末尾 [] ?我们不想添加任何进一步的修改,因此我们添加了组合的“中性元素”,即恒等函数 id :

 foldr (.) id ((\x -> x + 1) : (\y -> y + 2) : []) 

这等于

 (\x -> x + 1) . (\y -> y + 2) . id

我们越来越近了。我们需要一个像 (.) 这样的组合运算符但对于一元函数,它可以组合两个一元函数并产生另一个。某种类型的东西Monad m => (a -> m a) -> (a -> m a) -> a -> m aLooking for the signature in Hoogle ,我们发现稍微更通用(但仍然合适)的运算符 (<=<) :

 (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c

只剩下一个细节:一元函数组合的“同一性”是什么?嗯,是return ,这将纯值置于“中性”单子(monad)上下文中。以Maybe为例, return就是 Just构造函数。

所以,总而言之:如果你想组合一元函数列表,你可以这样做:

  combineMonadicFunctions :: Monad m => [a -> m a] -> a -> m a
combineMonadicFunctions fs = foldr (<=<) return fs

现在您可以使用 (>>=) 将结果应用到原始一元值。 .

关于haskell - 在 Haskell 中展开左 Binder ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36480421/

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