代码之家  ›  专栏  ›  技术社区  ›  Rick Minerich

无限类型(又称递归类型)在F#中不可能吗?

  •  12
  • Rick Minerich  · 技术社区  · 17 年前

    Sadek Drobi 当他在推特上提到F#似乎不支持无限类型时。事实证明,在C#中,你可以按照以下思路做一些事情:

    delegate RecDelegate<T> RecDelegate<T>(T x);
    

    然而,在我们两方面都做了一些实验之后,我们确定在F#中同样的东西似乎不可能隐式和显式的。

    明确的:

    type 'a specialF = 'a->specialF<'a>
    

    错误FS0191:此类型定义无效 涉及直接循环引用 通过缩写,struct字段 或继承关系。

    隐性的:

    let rec specialF (x: 'a) = specialF
    

    类型不匹配。期待a'b,但是 当统一“b”时将是无限的 和“a->”b’。

    当然,这些都是有意设计的简单样本。

    我想知道我是不是搞错了。也许我错过了一些必要的注释?

    3 回复  |  直到 17 年前
        1
  •  7
  •   kvb    17 年前

    你也可以这样做

    type 'a RecType = RecType of ('a -> 'a RecType)
    

    创建用于执行递归的命名类型。现在,这项工作:

    let rec specialF = RecType (fun _ -> specialF)
    
        2
  •  6
  •   Brian    17 年前
    type d<'T> = delegate of 'T -> d<'T>  //'
    let del : d<int> = null
    let anotherDel = del.Invoke(1).Invoke(2).Invoke(3)
    

    我认为您需要一个可直接在CLI中表示的命名类型来中断递归,因此在F#中,这意味着您还需要一个实际的委托类型。

        3
  •  3
  •   Kurt Schelfthout    17 年前

    递归记录类型也应该起作用。

    type A = { A : A }
    let rec a : A = { A = a }
    

    我对实际应用很感兴趣。甚至是不切实际的:)