gpt4 book ai didi

haskell - 定义不想定义的数据类型

转载 作者:行者123 更新时间:2023-12-04 12:14:03 25 4
gpt4 key购买 nike

我有一个用于 Haskell 中多项式的数据类型 Polynomial r 和一个 Ring 实例。 (class Ring r where plus :: r -> r -> r ; times :: r -> r -> r ; negative :: r -> r ; zero :: r ; one :: r——它只是 Num 的简化版本)。

现在我可以定义一个多项式,例如 gauss = x^2 + 1eisenstein = x^2 + x + 1然后在“多项式整数/(高斯)”中处理高斯整数或在“多项式整数/(艾森斯坦)”中处理爱森斯坦整数。这就是问题所在,我把它写在引号中是因为它不是真正的数据类型,而且我不知道如何定义它。

我首先尝试做类似 data Quotient p = Quot p p 的事情然后例如我们将有plus (Quot a i) (Quot b i') | i == i' = Quot (plus a b) i当然这已经很糟糕了,但甚至无法定义 onezero .所以我把它改成了data Quotient p = Quot p (Maybe p)我想我有一个使用它的工作实现,但你永远不知道 plus将起作用(它至少需要一个 Just ,如果有两个,它们必须相同)。

是否有任何类型安全(我的意思是不使用不安全函数)的方式来在 haskell 中进行编程?我很困惑。谢谢!

最佳答案

也许你可以用索引或标签来增加你的多项式类型?如果我理解正确,您的正常模块将类似于:

data Poly r = Poly r

class Ring r where
plus :: r -> r -> r
times :: r -> r -> r

instance Ring (Poly Integer) where
plus (Poly x) (Poly y) = Poly (x + y)
times (Poly x) (Poly y) = Poly (x * y)

gauss :: Poly Integer
gauss = Poly 1

eins :: Poly Integer
eins = Poly 2

并且您希望能够安全地区分环的两种“子类型”。也许您可以这样标记它们:
newtype PolyI i r = PolyI r

instance Show r => Show (PolyI i r) where
show (PolyI p) = show p

instance Ring (PolyI i Integer) where
plus (PolyI x) (PolyI y) = PolyI (x + y)
times (PolyI x) (PolyI y) = PolyI (x * y)

我们的 Ring 实例现在需要一个额外的类型参数 i ,我们可以通过简单的无构造函数类型来创建它。
data Gauss
data Eins

然后我们只需创建带有索引作为参数的特定多项式:
gaussI :: PolyI Gauss Integer
gaussI = PolyI 11

einsI :: PolyI Eins Integer
einsI = PolyI 20

Show上面的例子,我们得到以下输出:
*Poly> plus einsI einsI
40

接着
*Poly> plus einsI gaussI

Couldn't match expected type `Eins' with actual type `Gauss'
Expected type: PolyI Eins Integer
Actual type: PolyI Gauss Integer
In the second argument of `plus', namely `gaussI'

这和你要找的东西一样吗?

编辑:在对有关 newtype 的问题发表评论后,我认为如果您使用 NewtypeDeriving,这也可能是一个优雅的解决方案减轻重新实现 Poly Integer 的负担实例。我认为最终它会是相似的,如果比这种方法稍微优雅一点的话。

关于haskell - 定义不想定义的数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4612830/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com