Skip to content

Instantly share code, notes, and snippets.

@krisajenkins
Last active August 29, 2015 14:03
Show Gist options
  • Save krisajenkins/32ec783aa6ccfc8920ba to your computer and use it in GitHub Desktop.
Save krisajenkins/32ec783aa6ccfc8920ba to your computer and use it in GitHub Desktop.
Haskell Substitution Problem
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Control.Lens
import Data.Map (Map)
type SessionID = String
data Player = Player {
_outbox :: [String]
} deriving (Show,Eq)
data Board = Board {
_players :: Map SessionID Player
} deriving (Show,Eq)
makeLenses ''Player
makeLenses ''Board
--
-- | Pull the messages out of the given player's outbox.
dequeue :: SessionID -> Board -> (Board,[String])
dequeue sessionID board = (board',messages)
where path = (players . ix sessionID . outbox)
board' = set (players . ix sessionID . outbox) [] board
messages = view path board
main :: IO ()
main = undefined
-- | Pull the messages out of the given player's outbox.
dequeue :: SessionID -> Board -> (Board,[String])
dequeue sessionID board = (board',messages)
where path = (players . ix sessionID . outbox)
board' = set path [] board
messages = view path board
@krisajenkins
Copy link
Author

The first example compiles. But look at lines 26 & 27 - there's a duplication of the path there. So I substitute for example 2, and it fails with:

Example.hs:28:25-28: Warning: 
    Couldn't match type Identity with Const [String]
    Expected type: Getting [String] Board [String]
      Actual type: ([String] -> Identity [String])
                   -> Board -> Identity Board
    In the first argument of view, namely path
    In the expression: view path board

What am I missing?

@krisajenkins
Copy link
Author

And for future generations, here's the winning solution:

dequeueForPlayer :: SessionID -> Board -> (Board,[String])
dequeueForPlayer sessionID board = (board',messages)
  where path :: Traversal' Board [String]
        path = players . ix sessionID . outbox
        board' = set path [] board
        messages = view path board

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment