【发布时间】:2012-01-29 00:46:19
【问题描述】:
这是我目前所拥有的:
type Maybe<'a> = option<'a>
let succeed x = Some(x)
let fail = None
let bind rest p =
match p with
| None -> fail
| Some r -> rest r
let rec whileLoop cond body =
if cond() then
match body() with
| Some() ->
whileLoop cond body
| None ->
fail
else
succeed()
let forLoop (xs : 'T seq) f =
using (xs.GetEnumerator()) (fun it ->
whileLoop
(fun () -> it.MoveNext())
(fun () -> it.Current |> f)
)
whileLoop 可以很好地支持 for 循环,但我不知道如何获得支持的 while 循环。部分问题是while循环的翻译使用delay,在这种情况下我无法弄清楚。下面明显的实现可能是错误的,因为它不会延迟计算,而是运行它!
let delay f = f()
没有延迟也会阻碍try...with 和try...finally。
【问题讨论】:
-
你试过
let delay f = fun () -> f()吗? -
你看过
Maybe在FSharpx github.com/fsharp/fsharpx/blob/master/src/FSharpx.Core/Monad.fs中的monad实现了吗? -
查看stackoverflow.com/questions/4577050/… 了解一种方法。
-
特别是,
Delay f = f和Run f = f()应该可以工作,假设您相应地调整了While、Combine等的类型。 -
@Joh 你可以用
(unit -> M<'T>) -> (unit -> M<'T>)类型定义delay(正如@kvb 所建议的那样)。如果您修改其余定义以匹配此类型,一切都会正常工作。有关更复杂的定义,请参阅我的答案。 (诀窍是计算构建器可以简单地使用不同的类型进行非延迟和延迟计算)。