问题描述
F#是给我一些麻烦的类型推理规则。我正在写一个简单的计算,但建设者不能让我的泛型类型变量的约束权。
中的代码,我希望看起来在如下的 C#
类FinallyBuilder< TZ>
{
只读动作< TZ> finallyAction;
公共FinallyBuilder(动作< TZ> finallyAction)
{
this.finallyAction = finallyAction;
}
市民对结核病绑定< TA,TB>(TA X,Func键< TA,TB>续)其中TA:TZ
{// ^^^^^^ ^^^^^^^
试//这是什么让我头疼
{//在F#版本
返回续(X);
}
终于
{
finallyAction(X);
}
}
}
最好的(但非编译代码),我拿出在 F#版本至今:
键入FinallyBuilder<'Z> (finallyAction:'Z - >单位)=
会员this.Bind(X:'一)(续:'A - >'B)=
试续点¯x
终于finallyAction(X:>'Z)//非法投由于缺少约束
//注:更改为避免不良语法高亮这里SO。
不幸的是,我不知道我会怎么翻译其中TA:TZ
键入的绑定
法的约束。我想到了一个'当'它应该是类似:> Z
,但F#编译器不随地喜欢这一点,我总是受限于另一些通用型的变量结束。
莫非?有人请告诉我正确的F#代码
背景:我的目标是能写一个像这样的F#自定义工作流:
让清理=新FinallyBuilder(好玩点¯x - > ...)
清理{
让! X = ... // x和y将在
让被传递到上面的lambda函数! Y = ... //这个块的结束; x和y可具有不同类型的!
}
我不认为这可能写约束这样在F#(虽然我不知道是什么原因)。无论如何,syntacticalaly,你会想要写这样的事情(如布赖恩建议):
键入FinallyBuilder<'T> (finallyAction:'T - >单位)=
会员this.Bind<'A,'B当'A:> T>(X:'A)(续:'A - >'B)= //'
试续点¯x
终于finallyAction(X:>'T)
可惜的是,这提供了以下错误:
$ b满足$ b
这似乎是相同的情况下,如这个邮件列表。凡唐赛姆说以下内容:
This seems to be the same case as the one discussed in this mailing list. Where Don Syme says the following:
You can always solve this by using obj
in the function passed to your builder.
EDIT: Even when you use obj
, the values bound using let!
will have more specific types (when calling finallyAction
, F# will automatically cast the value of some type parameter to obj
):
type FinallyBuilder(finallyAction : obj -> unit) =
member x.Bind(v, f) =
try f v
finally finallyAction v
member x.Return(v) = v
let cleanup = FinallyBuilder(printfn "%A")
let res =
cleanup { let! a = new System.Random()
let! b = "hello"
return 3 }
这篇关于如何翻译一个`其中T:U`泛型类型参数从C#到F#的约束?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!