-3

定义循环类型的Integers表示以像这样工作:

data Integers = Zero | Next Integers | Prev Integers

并制作这个表示,类 Num 的实例,这意味着你应该可以(+), (*), (==), abs, signum, show使用Integers

直到现在我这样定义:

data Integers = Zero | Integers Int deriving (Show)

next :: Integers -> Integers
next Zero = Integers 1
next (Integers a) = Integers a + Integers 1

prev :: Integers -> Integers
prev (Integers 1) = Zero
prev (Integers a) = Integers a - Integers 1

instance Eq Integers where  
    Zero == Zero = True
    Integers a == Integers b = a == b  
    _ == _ = False

instance Num Integers where
    Integers a + Integers b = Integers (a + b)
    Integers a - Integers b = Integers (a - b)
    Integers a * Integers b = Integers (a * b)
    abs (Integers a) = Integers (abs a)
    signum (Integers a) = Integers (signum a)
    fromInteger a = Integers (fromInteger a)

但不符合data Integers = Zero | Next Integers | Prev Integers预期

4

1 回答 1

9
data Integers = Zero | Next Integers | Prev Integers

我将向您展示+,其余的应该很容易。

Zero + y = y
x + Zero = x

嗯,这很容易!

哦。还有一些其他情况。

尽管如此,我们已经处理了所有的Zero情况,所以现在我们只需要处理Prevand Next。他们是相反的,不是吗?因此,如果我们分别获得一个,它们将相互抵消。

Next x + Prev y = x + y
Prev x + Next y = x + y

现在我们只需要担心给定的数字都具有相同符号的情况。

Next x + Next y = Next (Next (x + y))
Prev x + Prev y = Prev (Prev (x + y))

(最后两个等式不是最有效的实现,但它们很容易理解。)

我们已经完成了定义+

其他一些功能更容易,一些更难(并且应该重用一些更简单的功能),但它们都涉及对/either/both参数的模式匹配并做适当的事情。大多数情况下,它们涉及递归,当给定递归数据结构时,通常在某种程度上是不可避免的。

于 2012-12-13T12:07:51.740 回答