英文:
How can you make an Option.bind but for bool returns from an imperative library?
问题
以下是您要求的代码的翻译部分:
// 使用函数风格的命令式库
// y 是一个 outref,但定义为 byref<'T>。您必须定义一个可变变量来获取输出。您不能使用:let boolRes, y = CreateY x
let CreateY (x, y: byref<'T>) =
if x > 0 then
y <- x
true
else false
// 我的代码
// 如果为真则继续
// 我无法让这个工作
let (|>>) f b =
match b with
| true -> f
| false -> false
// 一旦我获得了所有参数,我可以执行自己的 F# 风格操作
let doSomething1 y1 y2 y3 =
let y4: int = y1 + y2 + y3
printfn "我得到了 %i 和 %i 和 %i,现在我可以制作 %i" y1 y2 y3 y4
y4
let doSomething2 y4 =
let y5: int = y4 * 2
y5
let whyWontThisWork () =
let mutable y1 = 0
let mutable y2 = 0
let mutable y3 = 0
CreateY(0, &y1)
|>> CreateY(2, &y2)
|>> CreateY(3, &y3)
|>> doSomething1 y1 y2 y3 // 预期类型为 bool?
|> doSomething2 // 预期一个 bool -> a???
请注意,我已将 HTML 实体字符(如 &
和 >
)还原为它们的正常文本形式。如果需要更多帮助,请告诉我。
英文:
How do you do a bind-type operation with boolean results, then switch over to an F# style pipe workflow? I don't understand why the compiler complains when I switch from the "continue if to true" |>> to using a standard pipe at the end. The output of doSomething1 isn't being passed to |>>, so why does it care what its type is?
//Function style for an imperative library.
//y is an outref but defined as byref<'T>. You
//have to define a mutable var to get the
//output. You can't use: let boolRes, y = CreateY x
let CreateY (x, y: byref<'T>) =
if x > 0 then
y <- x
true
else false
//My code
//Continue If True
//I can't get this to work
let (|>>) f b =
match b with
| true -> f
| false -> false
//Once I get all my parameters, I can do my own f#
//style things.
let doSomething1 y1 y2 y3 =
let y4: int = y1 + y2 + y3
printfn "I get a %i and a %i and a %i and now I can make %i" y1 y2 y3 y4
y4
let doSomething2 y4 =
let y5: int = y4 * 2
y5
let whyWontThisWork () =
let mutable y1 = 0
let mutable y2 = 0
let mutable y3 = 0
CreateY(0, &y1)
|>> CreateY(2, &y2)
|>> CreateY(3, &y3)
|>> doSomething1 y1 y2 y3 //expected to have type bool?
|> doSomething2 //expecting a bool -> a???
答案1
得分: 1
以下是您提供的代码的翻译部分:
如果您愿意使用选项,我认为可以通过使用计算表达式来优雅地完成这项工作:
let CreateY (x, y: byref<int>) =
if x > 0 then
y <- x
true
else false
type Builder() =
member _.Return(value) = Some value
member _.ReturnFrom(opt : Option<_>) = opt
member _.Bind(b, f) = if b then f () else None
member _.Zero() = None
let build = Builder()
let doSomething1 y1 y2 y3 =
let y4: int = y1 + y2 + y3
printfn "I get a %i and a %i and a %i and now I can make %i" y1 y2 y3 y4
y4
let doSomething2 y4 =
let y5: int = y4 * 2
y5
let thisWillWork x =
let mutable y1 = 0
let mutable y2 = 0
let mutable y3 = 0
build {
do! CreateY(x, &y1)
do! CreateY(2, &y2)
do! CreateY(3, &y3)
return doSomething1 y1 y2 y3
|> doSomething2
}
thisWillWork 1 |> printfn "%A" // Some 12
thisWillWork 0 |> printfn "%A" // None
关键行是:
member _.Bind(b, f) = if b then f () else None
只是为了展示正在发生的事情,这将展开为:
build.Bind(CreateY(x, &y1), fun () ->
build.Bind(CreateY(2, &y2), fun () ->
build.Bind(CreateY(3, &y3), fun () ->
doSomething1 y1 y2 y3
|> doSomething2
|> Some)))
希望这有所帮助!
英文:
If you're willing to use options, I think this can be done elegantly using a computation expression:
let CreateY (x, y: byref<int>) =
if x > 0 then
y <- x
true
else false
type Builder() =
member _.Return(value) = Some value
member _.ReturnFrom(opt : Option<_>) = opt
member _.Bind(b, f) = if b then f () else None
member _.Zero() = None
let build = Builder()
let doSomething1 y1 y2 y3 =
let y4: int = y1 + y2 + y3
printfn "I get a %i and a %i and a %i and now I can make %i" y1 y2 y3 y4
y4
let doSomething2 y4 =
let y5: int = y4 * 2
y5
let thisWillWork x =
let mutable y1 = 0
let mutable y2 = 0
let mutable y3 = 0
build {
do! CreateY(x, &y1)
do! CreateY(2, &y2)
do! CreateY(3, &y3)
return doSomething1 y1 y2 y3
|> doSomething2
}
thisWillWork 1 |> printfn "%A" // Some 12
thisWillWork 0 |> printfn "%A" // None
The key line is:
member _.Bind(b, f) = if b then f () else None
Just to show what's going on, this desugars to:
build.Bind(CreateY(x, &y1), fun () ->
build.Bind(CreateY(2, &y2), fun () ->
build.Bind(CreateY(3, &y3), fun () ->
doSomething1 y1 y2 y3
|> doSomething2
|> Some)))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论