いくつかの問題:
x == 0
またはx == 1
ですが、x
ですChar
。つまり、 ですx == '0'
。
あなたが書く(xs:x)
。リストの最後に一致するパターンはありません。おそらく、最初にリストを逆にするヘルパー関数を使用してください。
[xs]
には 1 つの要素があり、 になることはありません""
。代わりに基本ケースを使用してください。
パターン マッチングは、等価性チェックよりも役立ちます。
**
は浮動小数点の累乗^
用、 は整数の累乗用
[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
。
(以前の計算を再利用し、心地よくクリーンなため、より優れています。)