我已经编写了一个Haskell程序,我想在其中实现一个进位保存加法器。我定义了type Nibble = (Bool, Bool, Bool, Bool)
和type Byte = (Nibble, Nibble)
。进位保存加法器的功能是carrySaveAdder :: Byte -> Byte -> Byte -> ( Byte , Byte )
。为了显示元组中的字节之一,我编写了一个小函数showBin :: Byte -> String
,可以将字节显示为二进制数。
如果在ghci中使用我在此处手动定义的值,例如let x = ((True,False,True,True),(False,False,False,False)) :: Byte
,则此功能可以很好地工作。一旦我尝试将其应用于元组的元素之一,它就不会执行预期的行为。它打印两个括号或单引号,并响应键盘输入,这似乎在等待某种类型的用户输入。如果我检查它的长度,虽然我看不到实际的输出,但它似乎是8(按预期)。
[期望的输出将是一个8位二进制数作为字符串,但是实际的输出是一个引号,除非手动中断,否则“输出”不会停止。
这种行为可能是什么原因?
type Nibble = (Bool, Bool, Bool, Bool)
type Byte = (Nibble, Nibble)
nand :: Bool -> Bool -> Bool
nand a b = not (a && b)
xor :: Bool -> Bool -> Bool
xor a b = nand( nand a (nand a b)) (nand b (nand a b))
fulladder :: Bool -> Bool -> Bool ->(Bool, Bool)
fulladder a b c = (xor c (xor a b) , (a &&b) || ((xor a b) && c))
carrySaveAdder :: Byte -> Byte -> Byte -> ( Byte , Byte )
carrySaveAdder ((a0, a1, a2, a3),(a4,a5,a6,a7)) ((b0, b1, b2, b3),(b4,b5,b6,b7)) ((c0, c1, c2, c3),(c4,c5,c6,c7)) =
let (r7,c7) = fulladder a7 b7 c7
(r6,c6) = fulladder a6 b6 c6
(r5,c5) = fulladder a5 b5 c5
(r4,c4) = fulladder a4 b4 c4
(r3,c3) = fulladder a3 b3 c3
(r2,c2) = fulladder a2 b2 c2
(r1,c1) = fulladder a1 b1 c1
(r0,c0) = fulladder a0 b0 c0
in (((r0,r1,r2,r3),(r4,r5,r6,r7)),((c0, c1, c2, c3),(c4,c5,c6,c7)))
showNib :: Nibble -> String
showNib (a,b,c,d) = map showIndividual ([a,b,c,d])
showBin :: Byte -> String
showBin (a,b) = showNib a ++ showNib b
showIndividual :: Bool -> Char
showIndividual a
| a = '1'
| not a = '0'
let x = ((True,False,True,True),(False,True,True,True)) :: Byte
let y = ((False,False,True,False),(False,True,True,True)) :: Byte
let z = ((False,False,True,False),(True,True,True,False)) :: Byte
let (sum,carry) = carrySaveAdder x y z
showBin carry
您的问题在这一行:
(r0,c0) = fulladder a0 b0 c0
您正在根据自身定义值c0
。当GHCi尝试对其进行评估以显示它时,它将陷入无限循环。
请注意,其中的每一行在其进位中都会创建相同的循环依赖关系。它们未正确连接在一起-进位位应从加法符中携带到[[next中,而不是本身。