在单例数据类型中使用 Nat/Natural 的正确方法是什么?

What is the proper way to use Nat/Natural in a singletons data type?

我正在 Haskell 中使用单例库编写具有多态变体的原型编程语言。我有一个基本的类型,看起来像这样:

import Data.Singletons.TH
import Data.Singletons
import GHC.Natural
import Data.Singletons.TypeLits

$(singletons [d|
  data MyType = 
      PredT
    | ProcT [MyType]
    | IntT
    | FloatT
    | StringT
    | FuncT MyType MyType
    | VariantT Natural [MyType]
    | UnionT [MyType]
  |])

VariantT 中的 Natural 参数用于标识特定变体,重要的是它实际上是 Natural(而不是像 Nat 那样定义为代数数据类型)出于效率原因。

问题是,根据这个定义,我得到:

Couldn't match expected type ‘Natural’
     with actual type ‘Demote Natural’

通常,根据我使用单例库的经验,当尝试将类型用作单例时,我会遇到这样的错误(无论如何我的理解),其中 SingKind 不支持该类型 e.x. for Char,所以我不知道为什么这不起作用。

我已经尝试了 Demote NaturalNat 以及不同的导入(我想也许我没有使用适合单身人士使用的正确“Nat”或“Natural”),所有这些都给我类似的错误。这里有什么问题?我是否必须为 Demote a != a 的类型编写单例手动生成的定义,或者我在这里遗漏了什么?

显然这是一个尚未解决的问题。如果我理解正确,目前 singletons TH 脚本通过重复使用与提升和降级类型相同的类型来工作,但是 Nat 完全打破了这个模型。长期的解决方案是等待 GHC 合并 NatNatural。同时,您将不得不手动复制或概括您的类型,或者滚动您自己的类型 Nat.

https://github.com/goldfirere/singletons/issues/478

作为短期修复,似乎可以扩展 TH 脚本 singletons 以自动执行类似的操作。对于广泛使用单例的人来说,这将是一个很好的贡献。