繁体   English   中英

Haskell 中的二进制数相加

[英]Addition of Binary Numbers in Haskell

我需要创建一个 function 将二进制数添加到另一个二进制数。 这是我的学习任务,我不太喜欢 Haskell 并且可以使用一些帮助。

我已经制作了我必须使用的数据类型。

data B = Zero
    | Even B
    | Odd B
    deriving (Show, Generic)
instance Listable B where tiers = genericTiers

Even表示 0, Odd表示 1, Zero表示结束。

..所以例如 Odd(Even(Odd Zero))) 等于 101 ......到目前为止,这就是我的 function。

plusB :: B -> B -> B
plusB (Odd a) (Odd b) = Odd (Even (plusB a b))
plusB (Even a) (Even b) =  Even (plusB a b)
plusB (Even a) (Odd b) = Odd (plusB a b)
plusB (Odd a) (Even b) = Odd (plusB a b)
plusB (Zero) (Zero) = .....

我认为我必须使用递归才能工作。

我希望这是有道理的。

如果假设Even构造函数返回偶数的图像,而Odd构造函数返回奇数的图像,这意味着最外面的构造函数映射到最右边(最低有效位)位。

在这种情况下,对OddEven更具描述性的名称可能是TwiceTwicePlus1

将 B 对象映射到整数:

toIntegerFromB :: B -> Integer
toIntegerFromB  Zero    =  0
toIntegerFromB (Even x) =  2*(toIntegerFromB x)
toIntegerFromB (Odd x)  =  1 + 2*(toIntegerFromB x)

至于添加两个B对象:

plusB :: B -> B -> B

我们有 3*3 = 9 个方程要写。 但其中有 5 个涉及中性元素Zero ,因此很容易编写:

plusB  (Zero)    (Zero)     =  Zero
plusB  (Zero)    (Even a)   =  Even a
plusB  (Even a)  (Zero)     =  Even a
plusB  (Zero)    (Odd a)    =  Odd a
plusB  (Odd a)   (Zero)     =  Odd a

关于剩下的 4 个等式,我们注意到数字 1 映射到Odd Zero ,而数字 2 映射到Even (Odd Zero)

OddEven分别视为TwicePlus1Twice

(奇数 a) + (奇数 b) ≃ (2 a+1)+(2 b+1) = 2 + 2*(a+b) ≃ 偶数 (奇零) + 偶数 (a+b)

因此等式:

plusB  (Odd a)   (Odd b)    =  plusB  (Even (Odd Zero))  (Even (plusB a b))

接下来,我们有:

(奇数 a) + (偶数 b) ≃ (2 a + 1) + (2 b) = 1 + 2*(a+b) ≃ 奇数 (a+b)

因此,使用对称性,两个方程:

plusB  (Even a)  (Odd b)    =  Odd  (plusB a b)
plusB  (Odd a)   (Even b)   =  Odd  (plusB a b)

最后剩下的等式更简单:

(偶数 a) + (偶数 b) ≃ (2 a)+(2 b) = 2*(a+b) ≃ 偶数 (a+b)

plusB  (Even a)  (Even b)   =  Even (plusB a b)

把它们放在一起:

plusB :: B -> B -> B
plusB  (Zero)    (Zero)     =  Zero
plusB  (Zero)    (Even a)   =  Even a
plusB  (Even a)  (Zero)     =  Even a
plusB  (Zero)    (Odd a)    =  Odd a
plusB  (Odd a)   (Zero)     =  Odd a
plusB  (Odd a)   (Odd b)    =  plusB  (Even (Odd Zero))  (Even (plusB a b))
plusB  (Even a)  (Even b)   =  Even (plusB a b)
plusB  (Even a)  (Odd b)    =  Odd  (plusB a b)
plusB  (Odd a)   (Even b)   =  Odd  (plusB a b)

与更常见的data Nat = Zero | Succ Nat data Nat = Zero | Succ Nat ,这种表示的优点是只需要 O(log(n)) 嵌套构造函数,而不是 O(n)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM