haskellenumshaskell-platform

How can I fuse two enums of the same type in Haskell?


I'm still very new to Haskell, and I'm curious as to how I would merge two Hand's together, so that, the first hand is placed on top of the second hand. I want it to be an infix operator, namely (<+). Here's some code to assist you. Essentially, what I'm saying is that I need help to "append" the two hands in some way.

data Rank = Numeric Integer | Jack | Queen | King | Ace
            deriving (Eq, Show)

data Suit = Hearts | Spades | Diamonds | Clubs
            deriving (Eq, Show)

data Card = Card Rank Suit
            deriving (Eq, Show)

data Hand = Empty | Add Card Hand
            deriving (Eq, Show)

(<+) :: Hand -> Hand -> Hand
(<+) Empty Empty = Empty
(<+) h Empty     = h
(<+) Empty h     = h
(<+) h1 h2       = h1 ++ h2

So far I've tried merge, append, mappend, and ++ as seen above.


Solution

  • You need to pattern match on one of the non-empty hands so that you can access the cards in it.

    (<+) :: Hand -> Hand -> Hand
    Empty <+ h = h
    h <+ Empty = h
    (Add c rest1) <+ h = Add c (rest1 <+ h)
    

    Strictly speaking, you don't need h <+ Empty = h, since the third rule can rebuild the hand once you reach Empty <+ h. But the second rule saves some computation.

    You can't use ++ et al. because none of them are defined for Hand. However, as was pointed out in a comment on your previous question, all Hand does is re-implement the built-in list type. You can take advantage of that by defining a new type.

    newtype Hand = Hand [Card]
    

    Then

    (<+) :: Hand -> Hand -> Hand
    (Hand h1) <+ (Hand h2) = Hand (h1 ++ h2)