【问题标题】:Compiler can't tell which record type with duplicate fields should be the function parameter type编译器无法判断哪个具有重复字段的记录类型应该是函数参数类型
【发布时间】:2014-07-27 18:33:47
【问题描述】:

我的程序有一些具有相同字段名称的记录类型(每种记录类型的含义不同)。编译器坚持匹配此记录形状的函数参数必须是最后声明的类型,即使我声明的记录实例具有明确的字段名称,并且始终将一致的类型传递给每个函数。

处理此问题的适当方法是什么?我知道我可以在函数上添加类型注释,但我觉得如果我以正确的方式做事,我不应该用类型注释来对抗编译器。

演示问题的最少代码:

type type1 = {x:int}
type type2 = {x:int}

let getX t =
    t.x

getX {type1.x=1}
|> ignore

编译器输出:

$ fsharpc --nologo test.fs


/tmp/typetest/test.fs(7,6): error FS0001: This expression was expected to have type
    type2    
but here has type
    type1    

【问题讨论】:

    标签: f# record


    【解决方案1】:

    有几种方法可以解决这个问题:

    1. 按照您的建议键入注释:

      let getX (t : type1) =
          t.x
      
    2. 在定义冲突类型之前定义getX

      type type1 = {x:int}
      
      let getX t =
          t.x
      
      type type2 = {x:int}
      
    3. 调用函数时不要显式指定类型:

      getX {x=1}
      

    哪些选项是“正确”的方式在很大程度上取决于具体情况。

    【讨论】:

      【解决方案2】:

      除了 p.s.w.g 的回答之外,您还可以考虑使用模块 划分范围。

      module A =
          type type1 = {x:int}
      
      module B =
          type type2 = {x:int}
      
      module C =
          // only make type1 visible in C
          open A  
      
          let getX t =
              t.x
      
          getX {type1.x=1}
          |> ignore
      

      我会说,在 F# 中,有两条记录 在同一个命名空间中使用相同的标签有点代码味道。

      【讨论】:

        【解决方案3】:

        您可以在getX 上使用constraint

        let inline getX (t: ^T) =
            (^T : (member x: int) (t))
        

        但是试图使其更通用(而不是要求属性 xint):

        let inline getX_generic (t: ^T) : 'U = 
            (^T : (member x : 'U) (t))
        

        在 F# 解释器、编译器和运行时存在问题。

        F# 解释器崩溃了,编译器认为getX_generic 返回一个obj 而不是int,当你运行它时,它不会计算。

        F# 作为一种新语言存在一些错误 - 如果您希望它正常工作 - 我建议您将这些问题记录在错误报告中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-27
          • 2015-06-28
          • 2017-05-20
          • 1970-01-01
          • 1970-01-01
          • 2013-03-04
          相关资源
          最近更新 更多