Haskell 如何将函数语言上的数字塔形式化?

Haskell 如何将函数语言上的数字塔形式化?,haskell,data-structures,functional-programming,idris,Haskell,Data Structures,Functional Programming,Idris,每个人都知道在依赖类型的函数语言上表达自然数的优雅方式: data Nat = Zero | Succ Nat 整数、分数、实数、复数和四元数对于实际编程应用也非常重要。可以通过以下方式实施: data Integer = Integer (sign : Bool) (modulus : Nat) data Fraction = Fraction (dividend : Nat) (divisor : Nat) data Real = Real (exponent : I

每个人都知道在依赖类型的函数语言上表达自然数的优雅方式:

data Nat = Zero | Succ Nat
整数、分数、实数、复数和四元数对于实际编程应用也非常重要。可以通过以下方式实施:

data Integer    = Integer (sign : Bool) (modulus : Nat)
data Fraction   = Fraction (dividend : Nat) (divisor : Nat)
data Real       = Real (exponent : Integer) (fraction : Nat)
data Complex    = Complex Real Real
data Quaternion = Quaternion Real Real Real Real

但没有一个能像NAT那样真实地反映其类型的实际结构/性质。例如,整数与实际整数不同构(因为零出现两次)。Reals需要超过一百万个单元来存储(3.141592),但甚至不需要100个单元来存储(4096),这看起来是不平衡的。复数只是实数的一个元组,它并不真正反映复数是什么。我想知道用函数式编程语言表达数字之塔的自然、优雅的方式是什么?

我意识到这是一个老问题,我的答案是用Scala而不是Haskell/Idris,但看看他们是如何用Scala实现的可能会很有趣。这里的方法是首先建立代数结构的层次结构(即,
半群
/
/
/
字段
/等),然后在其上实例化数值类型,添加数值方法中的各种算法。我相信你可以从中找到一些有用的想法。

你为什么不认为这“准确地反映了什么是
复合体”
?(也就是说,你的
Real
只包含有限长的十进制值,这是有理数的一个严格子集。)我的意思是,我想你可以将其表示为实数多项式mod x^2+1,但我不清楚你的反对意见是什么。此外,结构,例如,即使是真正同构的,也会影响性能和易用性。我可以将自然数编码为
data-Nat=Add-Nat-Nat | FloorHalf-Nat | Two | Zero
,但在上面实现代数算法会非常混乱。很明显,这并不能很好地代表Nats。我认为我的任意编码也是如此……我想你会发现性能和数学优雅是相互冲突的目标。你可以先用二进制表示自然,例如用
[Bool]
,但你的目的并不明确。你可能想读一点关于同伦类型理论的知识。沉重的东西,但它深入到了非唯一表示的整个问题中。下面是一个关于如何在Haskell中实现这些实数表示的视频: