title: On Haskell, what is the linguistic way to represent a card effect for a card game?
body: <p>I have a simple one-player Card Game:</p>
  
  <pre><code>data Player = Player {
      _hand :: [Card],
      _deck :: [Card],
      _board :: [Card]}
  $(makeLenses ''Player)
  </code></pre>
  
  <p>Some cards have an effect. For example, "Erk" is a card with the following effect:</p>
  
  <pre><code>Flip a coin. If heads, shuffle your deck.
  </code></pre>
  
  <p>I've implemented it as such:</p>
  
  <pre><code>shuffleDeck :: (MonadRandom m, Functor m) =&gt; Player -&gt; m Player
  shuffleDeck = deck shuffleM
  
  randomCoin :: (MonadRandom m) =&gt; m Coin
  randomCoin = getRandom
  
  flipCoin :: (MonadRandom m) =&gt; m a -&gt; m a -&gt; m a
  flipCoin head tail = randomCoin &gt;&gt;= branch where
      branch Head = head
      branch Tail = tail
  
  -- Flip a coin. If heads, shuffle your deck.
  erk :: (MonadRandom m, Functor m) =&gt; Player -&gt; m Player
  erk player = flipCoin (deck shuffleM player) (return player)
  </code></pre>
  
  <p>While this certainly does the job, I find an issue on the forced coupling to the <code>Random</code> library. What if I later on have a card that depends on another monad? Then I'd have to rewrite the definition of every card defined so far (so they have the same type). I'd prefer a way to describe the logic of my game entirely independent from the Random (and any other). Something like that:</p>
  
  <pre><code>erk :: CardAction
  erk = do
      coin &lt;- flipCoin
      case coin of
          Head -&gt; shuffleDeck
          Tail -&gt; doNothing
  </code></pre>
  
  <p>I could, later on, have a <code>runGame</code> function that does the connection.</p>
  
  <pre><code>runGame :: (RandomGen g) =&gt; g -&gt; CardAction -&gt; Player -&gt; Player
  </code></pre>
  
  <p>I'm not sure that would help. What is the correct, linguistic way to deal with this pattern?</p>