Haskell 整数乘法

Haskell 整数乘法,haskell,integer,multiplication,Haskell,Integer,Multiplication,我有一个数据类型: data AbstractInteger = Zero | Succ AbstractInteger | Pred AbstractInteger deriving (Show, Eq) 我已经有两个功能: 1将AbstractInteger转换为整数: aiToInteger :: AbstractInteger -> Integer aiT

我有一个数据类型:

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.整数的加法:

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))
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)
但我建议尝试通过对参数使用模式匹配来实现函数,比如:

iToAi :: Integer -> AbstractInteger
iToAi a | a == 0 = Zero
        | a < 0 = Pred (iToAi (a + 1))
        | a > 0 = Succ (iToAi (a - 1))
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)
关键点是成功a可以与a+1相关联,这就是为什么成功a*b可以与a*b+b相关联。根据这个逻辑,Pred a*b被转换为a*b-b,这就是为什么这里需要负函数

plusAbs的实现方式与此类似:

a+1+b与1+a+b相同 a-1+b与a+b-1相同
逻辑与您的示例中相同,但您可以通过使用模式匹配来避免使用aiToInteger。

您可以利用plusAbs,将乘法实现为重复加法。您不能在自己的自定义整数上使用+。@是的,这是一个错误,我已经修复了它,但它仍然不起作用。我鼓励您在不使用aiToInteger的情况下实现plusAbs,以便更好地了解数据类型的实际工作方式。使用较大参数执行递归调用通常会导致非终止函数。您应该从参数中删除构造函数,而不是添加它们。您需要处理多个YABS SUCCA b=。。。和多个变量Pred a b=。。。。对于后者,您需要一个减法子程序,或者至少需要一个更容易实现的相反子程序。