[英]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
构造函数返回奇数的图像,这意味着最外面的构造函数映射到最右边(最低有效位)位。
在这种情况下,对Odd
和Even
更具描述性的名称可能是Twice
和TwicePlus1
。
将 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)
。
将Odd
和Even
分别视为TwicePlus1
和Twice
:
(奇数 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.