乘法AbstractInteger
问题描述:
我有一个数据类型:乘法AbstractInteger
data AbstractInteger = Zero
| Succ AbstractInteger
| Pred AbstractInteger
deriving (Show, Eq)
我已经有两个功能:
1)转换AbstractInteger成整数:
aiToInteger :: AbstractInteger -> Integer
aiToInteger (Zero) = 0
aiToInteger (Succ next) = 1 + (aiToInteger next)
aiToInteger (Pred prev) = (aiToInteger prev) - 1
2)加法AbstractInteger:
plusAbs :: AbstractInteger -> AbstractInteger -> AbstractInteger
plusAbs a b | aiToInteger a == 0 = b
| aiToInteger b == 0 = a
| aiToInteger a > 0 = (Succ (plusAbs (Pred a) b))
| otherwise = (Pred (plusAbs (Succ a) b))
但我不明白如何创建乘法函数。
我写了这个,但它不工作。
multiplyAbs :: AbstractInteger -> AbstractInteger -> AbstractInteger
multiplyAbs _ (Zero) = (Zero)
multiplyAbs (Zero) _ = (Zero)
multiplyAbs a (Succ Zero) = a
multiplyAbs (Succ Zero) b = b
multiplyAbs a b = (plusAbs a (timesAbs a (Pred(b))))
答
正如你已经实现aiToInteger
,你可能想实现iToAi
,是这样的:
iToAi :: Integer -> AbstractInteger
iToAi a | a == 0 = Zero
| a < 0 = Pred (iToAi (a + 1))
| a > 0 = Succ (iToAi (a - 1))
然后plusAbs
和multiplyAbs
将回落到抽象的转变整数到整数,对它们执行的操作并将它们转换回来:
plusAbs' :: AbstractInteger -> AbstractInteger -> AbstractInteger
plusAbs' a b = iToAi (aiToInteger a + aiToInteger b)
multiplyAbs' :: AbstractInteger -> AbstractInteger -> AbstractInteger
multiplyAbs' a b = iToAi (aiToInteger a * aiToInteger b)
但我建议试图通过执行功能使用的参数模式匹配,是这样的:
negative :: AbstractInteger -> AbstractInteger
negative Zero = Zero
negative (Succ a) = Pred (negative a)
negative (Pred a) = Succ (negative a)
multiplyAbs :: AbstractInteger -> AbstractInteger -> AbstractInteger
multiplyAbs Zero a = Zero
multiplyAbs (Succ a) b = plusAbs (multiplyAbs a b) b
multiplyAbs (Pred a) b = plusAbs (multiplyAbs a b) (negative b)
关键的一点是,Succ a
可以(a + 1)
关联,这就是为什么(Succ a) * b
可以a * b + b
关联。根据这个逻辑,(Pred a) * b
被转换为a * b - b
,这就是为什么你需要negative
函数在这里。
plusAbs
同样实现:
-
(a + 1) + b
相同1 + (a + b)
-
(a - 1) + b
相同(a + b) - 1
的逻辑是,就像在你的榜样,但你可以尽量避免使用aiToInteger
通过使用模式匹配。
你可以利用'plusAbs',实现乘法作为重复加法。你不能在你自己的自定义整数上使用'+'。 – chi
@chi是啊这是错误的,我已经修复它,但它仍然不起作用 – Max
我会鼓励你实现'plusAbs'而不使用'aiToInteger'来更好地感觉你的数据类型是如何工作的。 – chepner