F#Convert';对字符串的歧视性结合

F#Convert';对字符串的歧视性结合,f#,f#-interactive,discriminated-union,F#,F# Interactive,Discriminated Union,我试图将一个有区别的联合转换为字符串,但我不明白为什么这段代码不起作用 type 'a sampleType = | A of 'a | B of 'a let sampleTypeToString x = match x with | A (value) -> string value | B (value) -> string value 这是fsharp交互输出 sampleTypeToString A(2);; Stopped due to error Sy

我试图将一个有区别的联合转换为字符串,但我不明白为什么这段代码不起作用

type 'a sampleType =
 | A of 'a
 | B of 'a

let sampleTypeToString x =
 match x with
 | A (value) -> string value
 | B (value) -> string value
这是fsharp交互输出

sampleTypeToString A(2);;
 Stopped due to error
 System.Exception: Operation could not be completed due to earlier error
 Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized at 3,19
 This expression was expected to have type
     'obj'    
 but here has type
     'int'     at 3,21

这里有两个错误:函数应用程序语法和通用性丢失

函数应用程序语法 这是错误“函数参数应以空格或元组分隔…”

在表达式
sampleTypeToString A(2)
中,实际上有三个术语,而不是两个:

  • sampleTypeToString
  • A
  • (2)
  • 不要让
    a
    (2)
    之间缺少空格欺骗了你。不知何故,这些都不被视为“一种表达”<代码>A和
    (2)
    是单独的术语

    因此,整个表达式
    sampleTypeToString A(2)
    被解释为应用于两个参数的函数
    sampleTypeToString
    A
    (2)
    。当然,这不起作用,因为
    sampleTypeToString
    只接受一个参数,而术语
    A
    不适合,因为它的类型错误

    解决此问题的最简单方法是在应首先计算的内容周围加上括号:

       sampleTypeToString (A(2))
    
    当然,因为F#中的函数(或构造函数)应用程序本身并不需要括号,所以可以删除第一个集合:

       sampleTypeToString (A 2)
    
    或者,可以使用管道:

       sampleTypeToString <| A(2)
    
    或者,您可以将
    string
    的参数装箱,将其转换为
    obj

    let sampleTypeToString x =
     match x with
     | A (value) -> string (box value)
     | B (value) -> string (box value)
    
    但是,您需要稍微更改
    string
    的语义,因为它以区域性不变的方式转换为string。如果你把参数框起来,它基本上会回到
    obj.ToString()
    。另外,对于装箱的值,您还需要额外的堆分配

    或者,您可以取消
    string
    ,自己调用
    .ToString()

    let sampleTypeToString x =
     match x with
     | A (value) -> value.ToString()
     | B (value) -> value.ToString()
    

    请记住,这与调用
    string

    并不完全相同,您需要
    box
    这个:
    sampleTypeToString(A(box(6))
    。这是一个使这个特定示例工作的快捷方式,但您必须同意这不是预期的。不,这就是为什么它只是一个注释:)但我想知道这是否可以不用内联完成。是的,它可以。我的回答中有两个选项。结合@s952163 solution Work,这并不能完全解决问题。是的,我正在更新它。写得太多了,无法一次发布所有内容。但请注意,@s952163的解决方案实际上并没有满足您的需求。将数字装箱将其从
    int
    转换为
    obj
    ,这样您就失去了使用
    sampleType
    generic的全部意义。
    let sampleTypeToString x =
     match x with
     | A (value) -> value.ToString()
     | B (value) -> value.ToString()