【问题标题】:How to add equality comparisons (==) to a newtype in Haskell如何将相等比较(==)添加到 Haskell 中的新类型
【发布时间】:2015-04-28 20:47:19
【问题描述】:

我正在尝试在 Haskell 中定义一个名为“Poly”的新类型,其中类型是表示多项式表达式的“Num”列表。 [1,2,3] 对应于 3x^2 + 2x + 1,因此 [4,5,6,0,0...0] 是与 [4,5,6] 相同的多项式。

我创建了一个名为“chop”的辅助函数来从列表末尾删除 0,但我在比较两个列表时遇到了麻烦。任何想法为什么我使用“实例”在这里不起作用?

它可以编译,但是当您尝试比较 Poly 的 2 个实例时,WinGHCi 挂起。

newtype Poly a = P [a]
x :: Num a => Poly a

chop :: (Eq a, Num a) => Poly a -> Poly a
chop (P l) = if (last l) == 0 then chop (P $ init l) else P l

instance (Num a, Eq a) => Eq (Poly a) where
    (==) m n = if (chop m) == (chop n) then True else False

【问题讨论】:

  • 次要风格注释:代码if e then True else False等同于简单的e
  • BTW chop 具有二次复杂度,可以在线性时间 O(n) 内完成。

标签: haskell typeclass newtype


【解决方案1】:

问题在于您已将(==) 定义为自身递归。稍微简化一下你的定义,你有:

m == n = chop m == chop n

这样计算:

m == n
-> { definition of (==) }
chop m == chop n
-> { definition of (==) }
chop (chop m) == chop (chop n)
-> { definition of (==) }
chop (chop (chop m)) == chop (chop (chop n))
-> { ... }

您应该将相等性测试发送回多项式的相等性测试,而不是将其发送到列表的相等性。例如,一个人可能会写

m == n = let P m' = chop m; P n' = chop n in m' == n'

改为。

【讨论】:

  • 完全有效。但是,必须进行一个小的更改(“P”而不是“Poly”) m == n = let P m' = Chop m; P n' = 将 n 切入 m' == n'
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-18
  • 2021-04-19
  • 2017-09-22
相关资源
最近更新 更多