大久保弘崇
ex8.1
最終更新:
hirotakaohkubo
-
view
ex8.1
基底部をどちらかが nil で止まるようにすればいい。変更部分だけを示す。
adder (cin, ([ ], bs)) = bitAdder (cin, bs)
adder (cin, (as, [ ])) = bitAdder (cin, as)
ex8.2
次の問題で使うための部品と思われるので、使いやすいように、最終的なキャリーを別にするかわりに自分に追加して返す形にする。
adder2 :: ([Bit], [Bit]) -> [Bit]
adder2 ([], bs) = bs
adder2 (as, []) = as
adder2 (a:as, b:bs) = sum:sums ++ [cout] where
(sum, car) = halfAdd (a, b)
(sums, cout) = adder (car, (as, bs))
ex8.3
andn :: ([Bit], Bit) -> [Bit]
andn (as, b) = map (curry and2 b) as
multi :: ([Bit], [Bit]) -> [Bit]
multi (as, bs) = mbody (bs, []) where
mbody ([], ss) = ss
mbody (b:bs, ss) = t : mbody (bs, ts) where
(t:ts) = adder2 (ss, andn (as, b))
ちょっとドジると結果のビット長が無駄に伸びる。
ここのコードはそうならない。
ここのコードはそうならない。
ex8.4
真理値表替わりのパターンマッチで関数を作る方法は認められないので、
DSLとして提供されている関数で表されているゲートを組み合わせて作らなければならない。
DSLとして提供されている関数で表されているゲートを組み合わせて作らなければならない。
halfSub :: (Bit,Bit) -> (Bit,Bit)
halfSub (a, b) = (sub, bor) where
sub = xor2 (a, b)
bor = and2 (inv a, b)
fullSub :: (Bit,(Bit,Bit)) -> (Bit,Bit)
fullSub (bin,(a,b)) = (sub, bor) where
(sub1,bor1) = halfSub (a, b)
(sub, bor2) = halfSub (sub1, bin)
bor = xor2 (bor1, bor2)
bitSubber :: (Bit,[Bit]) -> ([Bit],Bit)
bitSubber (bin, []) = ([], bin)
bitSubber (bin, a:as) = (sub:subs, bout) where
(sub, bor) = halfSub (a, bin)
(subs, bout) = bitSubber (bor, as)
subber :: (Bit,([Bit],[Bit])) -> ([Bit],Bit)
subber (bin, (as, [])) = bitSubber (bin, as)
subber (bin, ([], bs)) = subber (bin, ([low], bs))
subber (bin, (a:as, b:bs)) = (sub:subs, bout) where
(sub,bor) = fullSub (bin, (a, b))
(subs,bout) = subber (bor, (as, bs))