有人在F#里建了一个懒惰的单子吗?

有人在F#里建了一个懒惰的单子吗?,f#,monads,lazy-evaluation,F#,Monads,Lazy Evaluation,我一直在读Chris Okasaki的书,我想知道是否有一种很好的方法可以在monad中使用F#来构建惰性算法,从而实现惰性计算(惰性monad)。Chris在SML中使用了悬架/强制语法的自定义扩展,但我想我们可以在F#中使用一个简单的monad。在F#中手动使用lazy和force看起来相当混乱 我发现这个方案已经实现了,但我不知道它有多适用 从我粗略的知识和研究来看,在合理的范围内,这似乎是可行和可取的 请让我知道:)要导入冈崎代码,为什么不使用F#lazy关键字和一些辅助语法来表示强制,

我一直在读Chris Okasaki的书,我想知道是否有一种很好的方法可以在monad中使用F#来构建惰性算法,从而实现惰性计算(惰性monad)。Chris在SML中使用了悬架/强制语法的自定义扩展,但我想我们可以在F#中使用一个简单的monad。在F#中手动使用lazy和force看起来相当混乱

我发现这个方案已经实现了,但我不知道它有多适用

从我粗略的知识和研究来看,在合理的范围内,这似乎是可行和可取的


请让我知道:)

要导入冈崎代码,为什么不使用F#
lazy
关键字和一些辅助语法来表示强制,例如:

let (!) (x: Lazy<'T>) : 'T = x.Value
let(!)(x:Lazy=
Lazy.CreateFromValue(x)
成员this.Bind(x:Lazy-Lazy)=
懒惰(fx.Value).Value
let test()=
让v=
懒惰的{
设!x=1
让!y=懒惰2
返回x+y
}
v、 价值观

let(!)(x:Lazy我不确定这是否有帮助,但是如果您出于某种原因特别想:

type ('a, 'b) lazyT = Lz of 'a * ('a -> 'b)

let force (Lz (a, e)) = e a
let pack x = Lz(x, (fun i -> i))

type MyLazyBuilder =
  | Mylazy
  member this.Bind(x, f) =
      match x with
       | Lz(xa, xe) -> 
             Lz(xa, fun x -> force (f (xe x)))
  member this.Return(x) = pack x

let sth =
    Mylazy {
        let! x = pack 12
        let! y = pack (x + 1)
        return y * x
    }
let res = force sth
(缺少力只计算一次的部分)


很晚了,但我认为这是值得建议的。

这似乎很相关:Good link@Robert HarveyYes,我的意思是“计算生成器”:)也许它没有什么用处,但我确实喜欢使用“return”的算法不需要显式强制。我还希望在c表达式中自动强制递归解构,例如let!(,(z:zs))=xys,其中z:zs来自惰性流。但我不知道这是否可行。此外,我想我喜欢划分F#处于“惰性评估”模式的时间。最后,我仍然是一个FP noob,所以我的品味/欲望可能没有意义:)对于它的价值,我不认为(!)对于处理惰性值来说,这是一个非常好的别名,因为它已经与ref单元格关联。但是,我认为总体方法是好的…可能使用(!!)事实上,你可以选择任何
!x
操作符。不过,为了简洁起见,我通常会在代码中局部重载
。Bryan,通过在生成器的Bind方法中添加另一个重载,这种解构可能是可行的。tpyvo,对不起,我在这方面有点不知所措。你能告诉我如何添加这种类型的操作符吗超载?
type ('a, 'b) lazyT = Lz of 'a * ('a -> 'b)

let force (Lz (a, e)) = e a
let pack x = Lz(x, (fun i -> i))

type MyLazyBuilder =
  | Mylazy
  member this.Bind(x, f) =
      match x with
       | Lz(xa, xe) -> 
             Lz(xa, fun x -> force (f (xe x)))
  member this.Return(x) = pack x

let sth =
    Mylazy {
        let! x = pack 12
        let! y = pack (x + 1)
        return y * x
    }
let res = force sth