Skip to content

Instantly share code, notes, and snippets.

@blouerat
Last active August 29, 2015 14:02
Show Gist options
  • Save blouerat/2444c5f256147ee68ccf to your computer and use it in GitHub Desktop.
Save blouerat/2444c5f256147ee68ccf to your computer and use it in GitHub Desktop.
1HaskellADay: collect (a room traversal)
import Control.Applicative
{- You have a list of rooms, each rooms has two doors and contain one element.
To enter a room, the first door must be opened. To leave a room, the second door
must be open. It means that if you want to move from one room to the next one,
both the second door of the first room and the first door of the second room.
-}
data Room a = Room (Bool, Bool) a
{- | Given a list of rooms, we want to go as far as we can and collect the elements
in he room. This is the purpose of the function `collect`.
Examples:
>>> collect [Room (True, True) 1, Room (True, False) 2, Room (True, False) 3]
[1,2]
>>> collect [Room (False, True) 1, Room (True, False) 2, Room (True, False) 3]
[]
>>> collect [Room (True, True) 'a', Room (False, True) 'b', Room (True, True) 'c']
['a']
-}
collect :: [Room a] -> [a]
collect = map element . uncurry (++) . (fmap $ filter firstOpen . take 1) . span bothOpen
where doors (Room ds _) = ds
element (Room _ a) = a
firstOpen = fst . doors
bothOpen = uncurry (&&) . doors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment