【问题标题】:Are Infinite Types (aka Recursive Types) not possible in F#?无限类型(又名递归类型)在 F# 中是不可能的吗?
【发布时间】:2009-08-04 16:48:00
【问题描述】:

当我在 Twitter 上与 Sadek Drobi 聊天时,我被告知 F# 似乎不支持无限类型。事实证明,在 C# 中,您可以按照以下方式进行操作:

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

但是,在我们对这两个部分进行了一些实验之后,我们确定在 F# 中,无论是隐式还是显式,都似乎不可能。

显式:

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

错误 FS0191:此类型定义 涉及立即循环引用 通过缩写,结构字段 或继承关系。

隐式:

let rec specialF (x: 'a) = specialF

类型不匹配。期待一个'b但是 给定一个'a->'b。结果类型 统一''b'时将是无限的 和''a -> 'b'。

当然,这些都是故意简单的示例。

我想知道我是不是弄错了。也许我错过了某种必要的注释?

【问题讨论】:

  • 这里有实际应用吗,还是这个问题只是为了好玩而调查的结果?
  • 据我了解,没有实用的引用透明应用程序。然而,一个例子是,对于某种封闭的可变状态,这对于重复应用很有用。例如:add(1)(2)(3)(4) -- 可以完成任意数量的应用程序。
  • 这是我编写的一个 OCaml 程序,它使用此功能来避免使用 rectypes 的间接级别。 ffconsultancy.com/languages/ray_tracer/code/1/ray.ml

标签: f# types type-inference


【解决方案1】:

你也可以这样做

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

创建一个命名类型,通过它执行递归。现在可以了:

let rec specialF = RecType (fun _ -> specialF)

【讨论】:

【解决方案2】:
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】:

    递归记录类型也应该可以工作。

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

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

    【讨论】:

      猜你喜欢
      • 2015-09-19
      • 1970-01-01
      • 2012-07-17
      • 1970-01-01
      • 2018-03-23
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多