gpt4 book ai didi

f# - 为什么这个计算表达式构建器在我的 for 循环中期望 "unit"?

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

这是 this question 的后续问题.

我正在尝试创建一个计算表达式构建器,它通过自定义操作累积一个值,同时还支持标准 F# 语言构造。为了讨论一个简单的例子,我使用了一个构建 F# 列表的计算表达式。感谢 kvb 和 Daniel 的建议,我走得更远,但仍然遇到了 for 的问题循环。

builder :

type Items<'a> = Items of 'a list

type ListBuilder() =
member x.Yield(vars) = Items [], vars
member x.Run(l,_) = l
member x.Zero() = Items [], ()
member x.Delay f = f()
member x.ReturnFrom f = f

member x.Combine((Items curLeft, _), (Items curRight, vars)) =
(Items (curLeft @ curRight), vars)

member x.Bind(m: Items<'a> * 'v, f: 'v -> Items<'a> * 'o) : Items<'a> * 'o =
let (Items current, vals) = m
x.Combine(m, f vals)

member x.While(guard, body) =
if not (guard()) then
x.Zero()
else
x.Bind(body, fun () -> x.While(guard, body))

member x.TryWith(body, handler) =
try
x.ReturnFrom(body())
with e ->
handler e

member x.TryFinally(body, compensation) =
try
x.ReturnFrom(body())
finally
compensation()

member x.Using(disposable:#System.IDisposable, body) =
let body' = fun() -> body disposable
x.TryFinally(body', fun () ->
match disposable with
| null -> ()
| disp -> disp.Dispose())

member x.For(xs:seq<'a>, body) =
x.Using(xs.GetEnumerator(), fun enum ->
x.While(enum.MoveNext, x.Delay(fun () -> body enum.Current)))

[<CustomOperation("add", MaintainsVariableSpace=true)>]
member x.Add((Items current, vars), [<ProjectionParameter>] f) =
Items (current @ [f vars]), vars

[<CustomOperation("addMany", MaintainsVariableSpace=true)>]
member x.AddMany((Items current, vars), [<ProjectionParameter>] f) =
Items (current @ f vars), vars


let listBuilder = ListBuilder()

let build (Items items) = items

这个版本允许我以前做不到的事情,例如:
let stuff = 
listBuilder {
let x = 5 * 47
printfn "hey"
add x
addMany [x .. x + 10]
} |> build

但是,我仍然收到关于这个的编译器错误:
let stuff2 =
listBuilder {
for x in 1 .. 50 do
add x
} |> build

在这种情况下,IDE 将 for x in 中的 x 加下划线。并告诉我,“这个表达式的类型应该是 unit,但这里的类型是 int。”

我不太清楚为什么它期望循环变量是 unit 类型。显然我在某处得到了错误的方法签名,我怀疑我没有在我应该到达的每个地方都通过我的累积状态,但是编译器错误确实没有帮助我缩小我出错的地方。任何建议,将不胜感激。

最佳答案

直接原因是您的While函数约束body的类型.但是,一般而言,您不能在同一个计算表达式中同时使用自定义操作和控制流运算符,因此我认为即使修复了签名,您也永远无法完全按照自己的意愿行事。

关于f# - 为什么这个计算表达式构建器在我的 for 循环中期望 "unit"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23144744/

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