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

标签 haskell types typeclass

我有一个用于 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/

相关文章:

haskell - 如何将列表一元函数转换为广度优先搜索?

Ruby 数组模式匹配

scala - Scala 中的 'yield' 是否等同于 map 函数?

scala - 概括一个 "next permutation"函数

java - ArrayList 的类型不兼容错误

haskell - 调用函数的haskell案例

Java动态返回类型?

haskell - 具有多态类型的 STUArray

haskell - 这个多参数类型类可以简化吗?

Haskell:重叠实例