[英]Addition of Binary Numbers in Haskell
I need to create a function to add a binary number to another one.我需要创建一个 function 将二进制数添加到另一个二进制数。 It's a task for my study and I'm not that much into Haskell and could use some help.这是我的学习任务,我不太喜欢 Haskell 并且可以使用一些帮助。
I already made the datatype which I have to use.我已经制作了我必须使用的数据类型。
data B = Zero
| Even B
| Odd B
deriving (Show, Generic)
instance Listable B where tiers = genericTiers
Even
means 0, Odd
means 1 and Zero
is the end. Even
表示 0, Odd
表示 1, Zero
表示结束。
..so for example Odd(Even(Odd Zero))) is equal to 101... and that is my function so far. ..所以例如 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) = .....
I think that I have to use recursion for it to work.我认为我必须使用递归才能工作。
I hope that makes sense.我希望这是有道理的。
If you assume that the Even
constructor returns the image of an even number, and that the Odd
constructor returns the image of an odd number, this implies that the outermost constructor maps to the rightmost (least significant) bit.如果假设Even
构造函数返回偶数的图像,而Odd
构造函数返回奇数的图像,这意味着最外面的构造函数映射到最右边(最低有效位)位。
In that case, more descriptive names for Odd
and Even
could be Twice
and TwicePlus1
.在这种情况下,对Odd
和Even
更具描述性的名称可能是Twice
和TwicePlus1
。
Mapping B objects to Integers:将 B 对象映射到整数:
toIntegerFromB :: B -> Integer
toIntegerFromB Zero = 0
toIntegerFromB (Even x) = 2*(toIntegerFromB x)
toIntegerFromB (Odd x) = 1 + 2*(toIntegerFromB x)
As for the addition of two B objects:至于添加两个B对象:
plusB :: B -> B -> B
we have 3*3 = 9 equations to write.我们有 3*3 = 9 个方程要写。 But 5 of them involves Zero
which is the neutral element, and so are quite easy to write:但其中有 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
Regarding the 4 remaining equations, we note that number 1 maps to Odd Zero
and that number 2 maps to Even (Odd Zero)
.关于剩下的 4 个等式,我们注意到数字 1 映射到Odd Zero
,而数字 2 映射到Even (Odd Zero)
。
Thinking of Odd
and Even
as TwicePlus1
and Twice
respectively:将Odd
和Even
分别视为TwicePlus1
和Twice
:
(Odd a) + (Odd b) ≃ (2 a+1)+(2 b+1) = 2 + 2*(a+b) ≃ Even (Odd Zero) + Even (a+b) (奇数 a) + (奇数 b) ≃ (2 a+1)+(2 b+1) = 2 + 2*(a+b) ≃ 偶数 (奇零) + 偶数 (a+b)
Hence the equation:因此等式:
plusB (Odd a) (Odd b) = plusB (Even (Odd Zero)) (Even (plusB a b))
Next, we have:接下来,我们有:
(Odd a) + (Even b) ≃ (2 a + 1) + (2 b) = 1 + 2*(a+b) ≃ Odd (a+b) (奇数 a) + (偶数 b) ≃ (2 a + 1) + (2 b) = 1 + 2*(a+b) ≃ 奇数 (a+b)
Hence, using symmetry, the 2 equations:因此,使用对称性,两个方程:
plusB (Even a) (Odd b) = Odd (plusB a b)
plusB (Odd a) (Even b) = Odd (plusB a b)
The last remaining equation is easier:最后剩下的等式更简单:
(Even a) + (Even b) ≃ (2 a)+(2 b) = 2*(a+b) ≃ Even (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)
Compared to the more common data Nat = Zero | Succ Nat
与更常见的data Nat = Zero | Succ Nat
data Nat = Zero | Succ Nat
, this representation has the nice advantage of requiring only O(log(n)) nested constructors, instead of O(n). data Nat = Zero | Succ Nat
,这种表示的优点是只需要 O(log(n)) 嵌套构造函数,而不是 O(n)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.