Skip to content

Instantly share code, notes, and snippets.

@shoooe
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shoooe/47f810fec583019e4c1b to your computer and use it in GitHub Desktop.
Save shoooe/47f810fec583019e4c1b to your computer and use it in GitHub Desktop.
Playing around with the monad State. The program finds the number of sequences (defined as repetitions of a character) in a string.
import Control.Monad.State
data Sequence = Sequence { sequenceChar :: Char
, sequenceCount :: Integer } deriving (Eq, Show)
-- Without State monad.
-- Unused.
getNextSequence :: String -> (Sequence, String)
getNextSequence (h : []) = (Sequence h 1, [])
getNextSequence (h : ss) =
if h == (head ss) then
let (ns, rs) = getNextSequence ss
cns = sequenceCount ns
in (Sequence h (1 + cns), rs)
else (Sequence h 1, ss)
nextSequence :: State String Sequence
nextSequence = do
(h : ss) <- get
case ss of
[] -> do
put ss
return (Sequence h 1)
otherwise ->
if h == (head ss) then do
let (ns, rs) = runState nextSequence ss
let cns = sequenceCount ns
put rs
return $ Sequence h (1 + cns)
else do
put $ ss
return $ Sequence h 1
sequences :: String -> [Sequence]
sequences s =
let (seq, rest) = runState nextSequence s
in
if rest == "" then return seq
else seq : (sequences rest)
main = mapM_ (putStrLn . show) (sequences "Jefffrey")
-- Sequence {sequenceChar = 'J', sequenceCount = 1}
-- Sequence {sequenceChar = 'e', sequenceCount = 1}
-- Sequence {sequenceChar = 'f', sequenceCount = 3}
-- Sequence {sequenceChar = 'r', sequenceCount = 1}
-- Sequence {sequenceChar = 'e', sequenceCount = 1}
-- Sequence {sequenceChar = 'y', sequenceCount = 1}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment