F#中静态解析的字符串转换函数

时间:2014-02-03 22:09:05

标签: f#

我正在尝试在F#中创建一个函数,它将某些类型转换为字符串,而不是其他类型。目标是可以传递原语,但不能偶然传递复杂的对象。这是我到目前为止所做的:

type Conversions =
    static member Convert (value:int) =
        value.ToString()
    static member Convert (value:bool) =
        value.ToString()

let inline convHelper< ^t, ^v when ^t : (static member Convert : ^v -> string) > (value:^v) =
    ( ^t : (static member Convert : ^v -> string) (value))

let inline conv (value:^v) = convHelper<Conversions, ^v>(value)

不幸的是,我的conv函数遇到以下编译时错误:

A unique overload for method 'Convert' could not be determined based on type information
prior to this program point. A type annotation may be needed. Candidates: 
    static member Conversions.Convert : value:bool -> string, 
    static member Conversions.Convert : value:int -> string

我做错了什么?

3 个答案:

答案 0 :(得分:6)

这似乎有效:

type Conversions = Conversions with 
    static member ($) (Conversions, value: int) = value.ToString()
    static member ($) (Conversions, value: bool) = value.ToString()

let inline conv value = Conversions $ value

conv 1 |> ignore
conv true |> ignore
conv "foo" |> ignore //won't compile

答案 1 :(得分:4)

出于某种原因,似乎在约束中使用(^t or ^v)而不仅仅是^v使其有效。

type Conversions =
    static member Convert (value:int) =
        value.ToString()
    static member Convert (value:bool) =
        value.ToString()

let inline convHelper< ^t, ^v when (^t or ^v) : (static member Convert : ^v -> string)> value =
    ( (^t or ^v) : (static member Convert : ^v -> string) (value))

let inline conv value = convHelper<Conversions, _>(value)

当然,这意味着如果参数的类型从自身到字符串的静态方法Convert,该函数也会编译,但它不太可能咬你。

答案 2 :(得分:2)

好吧,丹尼尔的答案奏效了。这就是我最终想要的东西:

type Conversions = Conversions with
    static member ($) (c:Conversions, value:#IConvertible) =
        value.ToString()
    static member ($) (c:Conversions, value:#IConvertible option) =
        match value with
        | Some x -> x.ToString()
        | None -> ""

let inline conv value = Conversions $ value

IConvertible接口类型只是一种方便我捕获所有基元的方法。

这会导致以下行为(FSI):

conv 1         // Produces "1"
conv (Some 1)  // Produces "1"
conv None      // Produces ""
conv obj()     // Compiler error