2017-10-08 58 views
0

我有一个数据类型:乘法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)))) 
+0

你可以利用'plusAbs',实现乘法作为重复加法。你不能在你自己的自定义整数上使用'+'。 – chi

+0

@chi是啊这是错误的,我已经修复它,但它仍然不起作用 – Max

+7

我会鼓励你实现'plusAbs'而不使用'aiToInteger'来更好地感觉你的数据类型是如何工作的。 – chepner

回答

1

正如你已经实现aiToInteger,你可能想实现iToAi,是这样的:

iToAi :: Integer -> AbstractInteger 
iToAi a | a == 0 = Zero 
     | a < 0 = Pred (iToAi (a + 1)) 
     | a > 0 = Succ (iToAi (a - 1)) 

然后plusAbsmultiplyAbs将回落到抽象的转变整数到整数,对它们执行的操作并将它们转换回来:

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通过使用模式匹配。