F# 有没有一种方法可以让不同的实现做到呢!让我来!在计算表达式中?

F# 有没有一种方法可以让不同的实现做到呢!让我来!在计算表达式中?,f#,computation-expression,F#,Computation Expression,我需要一个不同的行为来做!让我来!在我的自定义计算表达式中 我试图通过以下方式实现这一目标: type FooBuilder() = class member b.Bind<'T, 'U>(x:'T, f:unit->'U):'U = failwith "not implemented" //do! implementation member b.Bind<'T, 'U>(x:'T, f:'T->'U):'U = failwith "not i

我需要一个不同的行为来做!让我来!在我的自定义计算表达式中

我试图通过以下方式实现这一目标:

type FooBuilder() = class
    member b.Bind<'T, 'U>(x:'T, f:unit->'U):'U = failwith "not implemented" //do! implementation
    member b.Bind<'T, 'U>(x:'T, f:'T->'U):'U = failwith "not implemented" //let! implementation
    member b.Return<'T>(x:'T):'T = failwith "not implemented" //return implementation
end

let foo = FooBuilder()
let x = foo {
    do! ()
    return 2
}
type FooBuilder()=class
成员b.Bind(x:'T,f:unit->'U):'U=failwith“notimplemented”//do!实施
成员b.Bind(x:'T,f:'T->'U):'U=failwith“notimplemented”//let!实施

如果要保留
let中使用的
Bind
操作,请返回泛型,那么就没有办法说F#在翻译
do(重载必须重叠)

一般来说,如果你想让
有不同的行为,那就让我来吧和对于
do则表明您的计算表达式可能定义不正确。这个概念非常灵活,它不仅可以用于声明单子,还可以用于更多的事情,但是您可能把它扩展得太远了。如果你能写更多关于你想要达到的目标的信息,那将是非常有用的。无论如何,这里有一些可能的解决办法

您可以添加一些额外的包装,并编写类似于
do!用“let!”包装“U:”U=faily
成员b.Bind(x:WrappedDo,f:unit->'U):'U=failwith“do!”
成员b.返回,f:'T->'U:'U=

如果typeof你可以尝试其他东西,有点难看,但应该可以:

let bindU (x, f) = f x // you must use x, or it'll make the Bind method less generic.
let bindG (x, f) = f x
member b.Bind(x : 'a, f : 'a -> 'b) =
    match box x with
    | :? unit -> bindU (x, f)
    | _ -> bindG (x, f)

它将a框起来(将其转换为
obj
)并检查它是否属于
单元类型
,然后重定向到正确的重载。

您可能还需要查看。它给你更多的自由与绑定关键字。
member b.Bind<'T, 'U>(x:Wrapped<'T>, f:'T->'U):'U = 
  if typeof<'T> = typeof<unit> then 
    failwith "do!" 
  else 
    failwith "let!" 
let bindU (x, f) = f x // you must use x, or it'll make the Bind method less generic.
let bindG (x, f) = f x
member b.Bind(x : 'a, f : 'a -> 'b) =
    match box x with
    | :? unit -> bindU (x, f)
    | _ -> bindG (x, f)