gpt4 book ai didi

haskell - 学术用途之外的延续单子(monad)是否有现实世界的适用性?

转载 作者:行者123 更新时间:2023-12-04 00:51:44 26 4
gpt4 key购买 nike

(后来的访问者:这个问题的两个答案都给出了很好的见解,如果你有兴趣,你可能应该同时阅读它们,我只能将一个作为 SO 的限制除外)

从我在网上找到的关于 continuation monad 的所有讨论中,他们要么提到了如何将它与一些琐碎的例子一起使用,要么解释说它是一个基本的构建 block ,如 Mother of all monads is the continuation monad 上的这篇文章中所述。 .

我想知道是否有超出这个范围的适用性。我的意思是,将递归函数或相互递归包装在延续单子(monad)中是否有意义?它有助于可读性吗?

这是取自 this SO post 的延续模式的 F# 版本:

type ContinuationMonad() =
member this.Bind (m, f) = fun c -> m (fun a -> f a c)
member this.Return x = fun k -> k x

let cont = ContinuationMonad()

它仅仅是为了学术兴趣,例如帮助理解单子(monad)或计算构建器吗?或者是否有一些现实世界的适用性,增加了类型安全性,或者它是否规避了其他难以解决的典型编程问题?

continuation monad with call/cc from Ryan Riley表明处理异常很复杂,但它没有解释它试图解决什么问题,示例也没有说明为什么它特别需要这个 monad。诚然,我只是不明白它的作用,但它可能是一个宝库!

(注意:我对了解 continuation monad 的工作原理不感兴趣,我想我对它有相当的了解,只是看不出它解决了什么编程问题。)

最佳答案

与使用显式递归实现的递归函数相比,我当然发现使用延续单子(monad)实现的递归函数更容易阅读。例如,给定这种树类型:

type 'a Tree = 
| Node of 'a * 'a Tree * 'a Tree
| Empty

这是在树上编写自下而上折叠的一种方法:
let rec fold e f t = cont {
match t with
| Node(a,t1,t2) ->
let! r1 = fold e f t1
let! r2 = fold e f t2
return f a r1 r2
| Empty -> return e
}

这显然类似于天真的折叠:
let rec fold e f t =
match t with
| Node(a,t1,t2) ->
let r1 = fold e f t1
let r2 = fold e f t2
f a r1 r2
| Empty -> return e

除了天真的折叠在深树上调用时会破坏堆栈,因为它不是尾递归的,而使用 continuation monad 编写的折叠不会。您当然可以使用显式延续来编写相同的东西,但在我看来,它们添加的困惑程度会分散算法结构的注意力(并且将它们放置在适当的位置并不是完全万无一失的):
let rec fold e f t k = 
match t with
| Node(a,t1,t2) ->
fold e f t1 (fun r1 ->
fold e f t2 (fun r2 ->
k (f r1 r2)))
| Empty -> k e

请注意,为了使它起作用,您需要修改 ContinuationMonad 的定义。包括
member this.Delay f v = f () v

关于haskell - 学术用途之外的延续单子(monad)是否有现实世界的适用性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41202721/

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