gpt4 book ai didi

调用组合时的 F# 计算表达式

转载 作者:行者123 更新时间:2023-12-04 14:40:13 25 4
gpt4 key购买 nike

我试图直接实现 Maybe单子(monad)。所以基本上整个表达式的计算结果为 Nothing如果中间步骤之一是 Nothing .

type Maybe<'a> =
| Just of 'a
| Nothing
type MaybeBuilder () =
member this.Combine ((first, second) : Maybe<'a> * Maybe<'b>) : Maybe<'b> =
printfn "Combine called"
match first with
| Nothing -> Nothing
| _ ->
match second with
| Nothing -> Nothing
| _ as a -> a
member this.Zero () = Just ()
member this.Bind((m, f) : Maybe<'a> * ('a -> Maybe<'b>)) =
printfn "Bind called"
match m with
| Nothing -> Nothing
| Just a -> f a
let MaybeMonad = MaybeBuilder()
let foobar =
MaybeMonad {
let! foo = Just "foo"
Just 1
Nothing
}

我期待 foobar翻译成 Just "foo" >>= fun foo -> Combine(Just 1, Nothing) ,但是 Combine没有被调用。

最佳答案

这不是计算表达式的预期编写方式。每次您想要“产生结果”时,您都需要在表达式的左侧添加一些关键字(return、return!、yield 或 yield!),在您的示例中,我将添加一个 return! :

let foobar =
MaybeMonad {
let! foo = Just "foo"
return! Just 1
return! Nothing
}

但是随后您需要将其定义添加到构建器中:
member this.ReturnFrom (expr) = expr

然后编译器会要求您添加一个延迟方法,在您的情况下,我认为您正在寻找类似的东西:
member this.Delay(x) = x()

差不多了,现在你有一个值限制,很可能是因为 Combine您定义的两个参数没有使用相同的类型,您可以修复它或在返回类型中添加类型注释:
let foobar : Maybe<int> =
MaybeMonad {
let! foo = Just "foo"
return! Just 1
return! Nothing
}

就是这样,现在你得到:
Bind called
Combine called

打印和:
val foobar : Maybe<int> = Nothing

如果您想了解 CE 的所有详细信息,请查看这篇不错的文章: https://www.microsoft.com/en-us/research/publication/the-f-computation-expression-zoo/

关于调用组合时的 F# 计算表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43992039/

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