Search code examples
haskelloutputghci

What is causing my program to only print parentheses?


I have written a Haskell program in which I want to implement a carry-save adder. I have defined type Nibble = (Bool, Bool, Bool, Bool) and type Byte = (Nibble, Nibble). The function of the carry-save adder is carrySaveAdder :: Byte -> Byte -> Byte -> ( Byte , Byte ). To display one of the bytes in the tuple, I wrote a small function showBin :: Byte -> String which can display the Byte as a binary number.

This function works perfectly fine if used in ghci with a value I defined there by hand such as let x = ((True,False,True,True),(False,False,False,False)) :: Byte. Once I try to apply it to one of the element of the tuple, it does not perform the expected behaviour. It prints either two parentheses or a single quotation mark and responds to keyboard input which makes it seem like it is waiting for user input of some kind. If I check out the length of it though,it seems to be 8 (as expected) although I cannot see the actual output.

The expected output would be an 8-bit binary number as a string but the actual output is a quotation mark and the "output" does not stop unless I manually interrupt it.

What could be a possible reason for this behaviour?

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

Solution

  • Your problem is in this line:

          (r0,c0) = fulladder a0 b0 c0
    

    You are defining the value c0 in terms of itself. When GHCi tries to evaluate it to show it, it gets into an infinite loop.

    Note that every line in there creates that same circular dependency in its carry bit. They're not wired together properly - a carry bit should carry from an addition into the next one, not itself.