4-Bit Ripple Carry Adder in Haskell

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
2
down vote

favorite












I recently started learning Haskell and had to program a 4 Bit Ripple Carry Adder that worked with tuples of the form



type Nibble = (Bool, Bool, Bool, Bool) 


Beforehand I wrote the functions



-- XOR operator
xor :: Bool -> Bool -> Bool
xor a b = (not (a && b) ) && (a || b)

-- Fulladder for 1-Bit binary numbers
-- Returns Tuple in the Form (add Carry, Sum)
fulladder :: Bool -> Bool -> Bool -> (Bool, Bool)
fulladder a b ci = ( (a && b) || ( (xor a b) && ci ), xor ci (xor a b) )

-- Second Element of (Bool, Bool)
saccess :: (Bool, Bool) -> Bool
saccess (f, a) = a

-- First Element of (Bool, Bool)
faccess :: (Bool, Bool) -> Bool
faccess (a, f) = a

-- 4-Bit Adder that does Nibble + Nibble = Nibble
rippleCarryAdder :: Nibble -> Nibble -> Nibble
rippleCarryAdder (a0, a1, a2, a3) (b0, b1, b2, b3) = (saccess (fulladder a0 b0 (faccess (fulladder a1 b1 (faccess (fulladder a2 b2 (faccess (fulladder a3 b3 False))))))), saccess (fulladder a1 b1 (faccess (fulladder a2 b2 (faccess (fulladder a3 b3 False))))), saccess (fulladder a2 b2 (faccess (fulladder a3 b3 False ))), saccess (fulladder a3 b3 False) )


I have the constraint that I can't change the types in the definitions of the functions fulladder and rippleCarryAdder. So one has to work with Nibble.

I would like to know if there is a more elegant way to work with the tuples returned by fulladder without defining a lot of other functions.







share|improve this question

























    up vote
    2
    down vote

    favorite












    I recently started learning Haskell and had to program a 4 Bit Ripple Carry Adder that worked with tuples of the form



    type Nibble = (Bool, Bool, Bool, Bool) 


    Beforehand I wrote the functions



    -- XOR operator
    xor :: Bool -> Bool -> Bool
    xor a b = (not (a && b) ) && (a || b)

    -- Fulladder for 1-Bit binary numbers
    -- Returns Tuple in the Form (add Carry, Sum)
    fulladder :: Bool -> Bool -> Bool -> (Bool, Bool)
    fulladder a b ci = ( (a && b) || ( (xor a b) && ci ), xor ci (xor a b) )

    -- Second Element of (Bool, Bool)
    saccess :: (Bool, Bool) -> Bool
    saccess (f, a) = a

    -- First Element of (Bool, Bool)
    faccess :: (Bool, Bool) -> Bool
    faccess (a, f) = a

    -- 4-Bit Adder that does Nibble + Nibble = Nibble
    rippleCarryAdder :: Nibble -> Nibble -> Nibble
    rippleCarryAdder (a0, a1, a2, a3) (b0, b1, b2, b3) = (saccess (fulladder a0 b0 (faccess (fulladder a1 b1 (faccess (fulladder a2 b2 (faccess (fulladder a3 b3 False))))))), saccess (fulladder a1 b1 (faccess (fulladder a2 b2 (faccess (fulladder a3 b3 False))))), saccess (fulladder a2 b2 (faccess (fulladder a3 b3 False ))), saccess (fulladder a3 b3 False) )


    I have the constraint that I can't change the types in the definitions of the functions fulladder and rippleCarryAdder. So one has to work with Nibble.

    I would like to know if there is a more elegant way to work with the tuples returned by fulladder without defining a lot of other functions.







    share|improve this question





















      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      I recently started learning Haskell and had to program a 4 Bit Ripple Carry Adder that worked with tuples of the form



      type Nibble = (Bool, Bool, Bool, Bool) 


      Beforehand I wrote the functions



      -- XOR operator
      xor :: Bool -> Bool -> Bool
      xor a b = (not (a && b) ) && (a || b)

      -- Fulladder for 1-Bit binary numbers
      -- Returns Tuple in the Form (add Carry, Sum)
      fulladder :: Bool -> Bool -> Bool -> (Bool, Bool)
      fulladder a b ci = ( (a && b) || ( (xor a b) && ci ), xor ci (xor a b) )

      -- Second Element of (Bool, Bool)
      saccess :: (Bool, Bool) -> Bool
      saccess (f, a) = a

      -- First Element of (Bool, Bool)
      faccess :: (Bool, Bool) -> Bool
      faccess (a, f) = a

      -- 4-Bit Adder that does Nibble + Nibble = Nibble
      rippleCarryAdder :: Nibble -> Nibble -> Nibble
      rippleCarryAdder (a0, a1, a2, a3) (b0, b1, b2, b3) = (saccess (fulladder a0 b0 (faccess (fulladder a1 b1 (faccess (fulladder a2 b2 (faccess (fulladder a3 b3 False))))))), saccess (fulladder a1 b1 (faccess (fulladder a2 b2 (faccess (fulladder a3 b3 False))))), saccess (fulladder a2 b2 (faccess (fulladder a3 b3 False ))), saccess (fulladder a3 b3 False) )


      I have the constraint that I can't change the types in the definitions of the functions fulladder and rippleCarryAdder. So one has to work with Nibble.

      I would like to know if there is a more elegant way to work with the tuples returned by fulladder without defining a lot of other functions.







      share|improve this question











      I recently started learning Haskell and had to program a 4 Bit Ripple Carry Adder that worked with tuples of the form



      type Nibble = (Bool, Bool, Bool, Bool) 


      Beforehand I wrote the functions



      -- XOR operator
      xor :: Bool -> Bool -> Bool
      xor a b = (not (a && b) ) && (a || b)

      -- Fulladder for 1-Bit binary numbers
      -- Returns Tuple in the Form (add Carry, Sum)
      fulladder :: Bool -> Bool -> Bool -> (Bool, Bool)
      fulladder a b ci = ( (a && b) || ( (xor a b) && ci ), xor ci (xor a b) )

      -- Second Element of (Bool, Bool)
      saccess :: (Bool, Bool) -> Bool
      saccess (f, a) = a

      -- First Element of (Bool, Bool)
      faccess :: (Bool, Bool) -> Bool
      faccess (a, f) = a

      -- 4-Bit Adder that does Nibble + Nibble = Nibble
      rippleCarryAdder :: Nibble -> Nibble -> Nibble
      rippleCarryAdder (a0, a1, a2, a3) (b0, b1, b2, b3) = (saccess (fulladder a0 b0 (faccess (fulladder a1 b1 (faccess (fulladder a2 b2 (faccess (fulladder a3 b3 False))))))), saccess (fulladder a1 b1 (faccess (fulladder a2 b2 (faccess (fulladder a3 b3 False))))), saccess (fulladder a2 b2 (faccess (fulladder a3 b3 False ))), saccess (fulladder a3 b3 False) )


      I have the constraint that I can't change the types in the definitions of the functions fulladder and rippleCarryAdder. So one has to work with Nibble.

      I would like to know if there is a more elegant way to work with the tuples returned by fulladder without defining a lot of other functions.









      share|improve this question










      share|improve this question




      share|improve this question









      asked May 10 at 12:31









      P-A

      134




      134




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          rippleCarryAdder is very hard to read. We can make it a lot easier to read if we use local bindings with let … in …:



          rippleCarryAdder :: Nibble -> Nibble -> Nibble
          rippleCarryAdder (a0, a1, a2, a3) (b0, b1, b2, b3) =
          let (r3, c3) = fulladder a3 b3 False
          (r2, c2) = fulladder a2 b2 c3
          (r1, c1) = fulladder a1 b1 c2
          (r0, _ ) = fulladder a0 b0 c1
          in (r0, r1, r2, r3)


          We also don't have to recalculate fulladder a3 b3 False four times.




          The functions faccess and saccess already exist and are called fst and snd.






          share|improve this answer





















          • That looks way better, thanks!
            – P-A
            May 10 at 14:18










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f194099%2f4-bit-ripple-carry-adder-in-haskell%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          3
          down vote



          accepted










          rippleCarryAdder is very hard to read. We can make it a lot easier to read if we use local bindings with let … in …:



          rippleCarryAdder :: Nibble -> Nibble -> Nibble
          rippleCarryAdder (a0, a1, a2, a3) (b0, b1, b2, b3) =
          let (r3, c3) = fulladder a3 b3 False
          (r2, c2) = fulladder a2 b2 c3
          (r1, c1) = fulladder a1 b1 c2
          (r0, _ ) = fulladder a0 b0 c1
          in (r0, r1, r2, r3)


          We also don't have to recalculate fulladder a3 b3 False four times.




          The functions faccess and saccess already exist and are called fst and snd.






          share|improve this answer





















          • That looks way better, thanks!
            – P-A
            May 10 at 14:18














          up vote
          3
          down vote



          accepted










          rippleCarryAdder is very hard to read. We can make it a lot easier to read if we use local bindings with let … in …:



          rippleCarryAdder :: Nibble -> Nibble -> Nibble
          rippleCarryAdder (a0, a1, a2, a3) (b0, b1, b2, b3) =
          let (r3, c3) = fulladder a3 b3 False
          (r2, c2) = fulladder a2 b2 c3
          (r1, c1) = fulladder a1 b1 c2
          (r0, _ ) = fulladder a0 b0 c1
          in (r0, r1, r2, r3)


          We also don't have to recalculate fulladder a3 b3 False four times.




          The functions faccess and saccess already exist and are called fst and snd.






          share|improve this answer





















          • That looks way better, thanks!
            – P-A
            May 10 at 14:18












          up vote
          3
          down vote



          accepted







          up vote
          3
          down vote



          accepted






          rippleCarryAdder is very hard to read. We can make it a lot easier to read if we use local bindings with let … in …:



          rippleCarryAdder :: Nibble -> Nibble -> Nibble
          rippleCarryAdder (a0, a1, a2, a3) (b0, b1, b2, b3) =
          let (r3, c3) = fulladder a3 b3 False
          (r2, c2) = fulladder a2 b2 c3
          (r1, c1) = fulladder a1 b1 c2
          (r0, _ ) = fulladder a0 b0 c1
          in (r0, r1, r2, r3)


          We also don't have to recalculate fulladder a3 b3 False four times.




          The functions faccess and saccess already exist and are called fst and snd.






          share|improve this answer













          rippleCarryAdder is very hard to read. We can make it a lot easier to read if we use local bindings with let … in …:



          rippleCarryAdder :: Nibble -> Nibble -> Nibble
          rippleCarryAdder (a0, a1, a2, a3) (b0, b1, b2, b3) =
          let (r3, c3) = fulladder a3 b3 False
          (r2, c2) = fulladder a2 b2 c3
          (r1, c1) = fulladder a1 b1 c2
          (r0, _ ) = fulladder a0 b0 c1
          in (r0, r1, r2, r3)


          We also don't have to recalculate fulladder a3 b3 False four times.




          The functions faccess and saccess already exist and are called fst and snd.







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered May 10 at 13:33









          Zeta

          14.3k23267




          14.3k23267











          • That looks way better, thanks!
            – P-A
            May 10 at 14:18
















          • That looks way better, thanks!
            – P-A
            May 10 at 14:18















          That looks way better, thanks!
          – P-A
          May 10 at 14:18




          That looks way better, thanks!
          – P-A
          May 10 at 14:18












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f194099%2f4-bit-ripple-carry-adder-in-haskell%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Chat program with C++ and SFML

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          Will my employers contract hold up in court?