一些问题:
x == 0
或者x == 1
,但是x
是一个Char
,所以你的意思是x == '0'
。
你写(xs:x)
。列表末尾没有匹配模式。也许使用先反转列表的辅助函数。
[xs]
有一个元素,永远不会""
。请改用基本情况。
模式匹配比相等检查更有帮助。
**
用于浮点幂,^
用于整数幂
你经常使用[xs]
你的意思xs
。您无需使用方括号来制作列表。
这是一个有效的重写:
negbin_dezi1 :: NegaBinary -> Integer
negbin_dezi1 xs = negbin (reverse xs) 0
negbin [] _ = 0
negbin (x:xs) n
| x == '0' = negbin xs (n+1)
| x == '1' = (-2)^n + (negbin xs (n+1))
使用模式匹配会更好:
negbin_dezi2 :: NegaBinary -> Integer
negbin_dezi2 xs = negbin (reverse xs) 0 where
negbin [] _ = 0
negbin ('0':xs) n = negbin xs (n+1)
negbin ('1':xs) n = (-2)^n + negbin xs (n+1)
但也许将 '0' 转换为 0 并将 '1' 转换为 1 并乘以它会更好:
val :: Char -> Int
val '0' = 0
val '1' = 1
negbin_dezi3 :: NegaBinary -> Integer
negbin_dezi3 xs = negbin (reverse xs) 0 where
negbin [] _ = 0
negbin (x:xs) n = val x * (-2)^n + negbin xs (n+1)
不过,我不会这样写:
一种完全不同的方法是同时考虑整个事情。
"10010" -rev> [0,1,0,0,1] -means> [ 0, 1, 0, 0, 1 ]
[(-2)^0, (-2)^1, (-2)^2, (-2)^3, (-2)^4]
所以让我们列出两个列表
powers = [(-2)^n | n <- [0..]]
coefficients = reverse.map val $ xs
并将它们相乘
zipWith (*) powers coefficients
然后加起来,给出:
negbin_dezi4 xs = sum $ zipWith (*) powers coefficients
where powers = [(-2)^n | n <- [0..]]
coefficients = reverse.map val $ xs
您可以重写powers
为map ((-2)^) [0..]
,
甚至更好:powers = 1:map ((-2)*) powers
。
(它更好,因为它重用了以前的计算并且非常干净。)