F# 成员约束 + ^a byref 参数
在尝试了一些 F# 成员约束功能并编写如下函数之后:
let inline parse< ^a when ^a : (static member Parse: string -> ^a) > s =
(^a: (static member Parse: string -> ^a) s)
效果非常好:
let xs = [ "123"; "456"; "999" ] |> List.map parse<int>
我正在尝试编写其他 func tryParse
,它使用静态方法 TryParse
并包装将解析结果转换为 'a option
类型,以便在 F# 中提供更好的支持。像这样的东西不能编译:
let inline tryParse s =
let mutable x = Unchecked.defaultof< ^a>
if (^a: (static member TryParse: string * ^a byref -> bool) (s, &x))
then Some x else None
错误是:
错误 FS0001:此表达式是 预计有类型 byref<'a> 但这里有类型 '参考
F# ref
-cells 也不起作用:
let inline tryParse s =
let x = ref Unchecked.defaultof< ^a>
if (^a: (static member TryParse: string * ^a byref -> bool) (s, x))
then Some x else None
我做错了什么?
After some playing around F# member constraints feature and writing function like this:
let inline parse< ^a when ^a : (static member Parse: string -> ^a) > s =
(^a: (static member Parse: string -> ^a) s)
That works perfectly fine:
let xs = [ "123"; "456"; "999" ] |> List.map parse<int>
I'm trying to write other func tryParse
, that uses static method TryParse
and wraps the parse result into 'a option
type for better support in F#. Something like this doesn't compiles:
let inline tryParse s =
let mutable x = Unchecked.defaultof< ^a>
if (^a: (static member TryParse: string * ^a byref -> bool) (s, &x))
then Some x else None
The error is:
error FS0001: This expression was
expected to have type
byref<'a> but here has type
'a ref
F# ref
-cells doesn't work too:
let inline tryParse s =
let x = ref Unchecked.defaultof< ^a>
if (^a: (static member TryParse: string * ^a byref -> bool) (s, x))
then Some x else None
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
更新
这似乎已在 F# 3.0 中修复。
旧答案:
我同意斯蒂芬的评论,这很可能是一个错误。 byref 类型有很多限制,因此它们不能很好地处理成员约束,这对我来说并不特别奇怪。这是使用反射的(丑陋的)解决方法:
UPDATE
This appears to be fixed in F# 3.0.
Old answer:
I agree with Stephen's comment that it's most likely a bug. There are many limitations on byref types, so it's not particularly surprising to me that they don't play well with member constraints. Here's an (ugly) workaround using reflection:
我认为这也是一个错误,涉及成员约束和 byref 类型。我可以通过更改成员约束的签名来制作一个稍微不那么难看的反射版本:
这个非常接近:
但我收到错误FS0421:此时无法使用变量“x”的地址 当我尝试编译它时。
I think it is a bug too, something with member constraints and byref types. I can make a slightly less ugly reflection version by changing the signature of the member constraint:
This one is very close:
but I get a error FS0421: The address of the variable 'x' cannot be used at this point when I try to compile it.
这可以编译,但仍然无法按预期工作:
在这种特定情况下,我不会使用反射,而是在 f# 中从 Parse 中重新创建 TryParse
This compiles but still does not work as expected:
in this specific case, rather than using reflection I would just recreate TryParse out of Parse in f#