F#成员约束+ ^ a byref参数 [英] F# member constraints + ^a byref parameters

查看:189
本文介绍了F#成员约束+ ^ a byref参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一些关于F#成员约束的功能和写函数之后,像这样:

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)

这完全正常:

let xs = [ "123"; "456"; "999" ] |> List.map parse<int>

我试图写其他函数 tryParse ,它使用静态方法 TryParse 并将解析结果包装到'一个选项类型中,以便更好地支持F#。这样的东西不编译:

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

错误是:


错误FS0001:表达式为
,预期类型为
byref <'a> ,但这里有
类型'a ref

F# ref --cells不起作用:

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

我做错了什么?

推荐答案

strong> UPDATE

UPDATE

这似乎在F#3.0中已修复。

This appears to be fixed in F# 3.0.

answer:

我同意Stephen的评论,这很可能是一个错误。对byref类型有很多限制,所以对我来说,它并不特别令人惊讶,他们不能很好地与成员约束。这里是一个使用反射的(丑陋的)解决方法:

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:

type parseDel<'a> = delegate of string * 'a byref -> bool

type Parser< ^a when ^a : (static member TryParse: string * ^a byref -> bool)> private ()=
  static let parser = System.Delegate.CreateDelegate(typeof<parseDel<'a>>, typeof<'a>.GetMethod("TryParse", [|typeof<string>; typeof<'a>.MakeByRefType()|])) :?> parseDel<'a>
  static member inline ParseDel = parser

let inline tryParse (s:string) =
  let mutable x = Unchecked.defaultof< ^a>
  if Parser<_>.ParseDel.Invoke(s, &x) then
    Some x
  else None

let one : int option = tryParse "1"

这篇关于F#成员约束+ ^ a byref参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆