suztomoの日記

To be a good software engineer

Evaluate iteratee: drop head

Let's perform the evaluation on head and drop.

drop :: Int -> IterV el ()
drop 0 = Done () Empty
drop n = Cont step
  where
    step (El _) = drop (n-1)
    step Empty = Cont step
    step EOF = Done () EOF

head :: IterV el (Maybe el)
head = Cont step
  where
    step (El el) = Done (Just el) Empty
    step Empty = Cont step
    step EOF = Done Nothing EOF

This is goal

*Main> run $ enum (drop 1 >> head) "abc"
Just (Just 'b')

The following steps are to generate the goal above.

run $ enum (drop 1 >> head) "abc"

run $ enum (drop 1 >>= (\x -> head)) "abc"

run $ enum (case (drop 1) of 
                       Done x e -> case ((\x -> head) x) of 
                            Done x' _ -> Done x' e
                            Cont k     -> k e
                       Cont k -> Cont (\str ->((k str) >>= (\x -> head)))
                    ) "abc"

-- Using drop rule. The step is bound to "drop 1"
run $ enum (case (Cont step) of 
                       Done x e -> case ((\x -> head) x) of 
                            Done x' _ -> Done x' e
                            Cont k     -> k e
                       Cont k -> Cont (\str ->((k str) >>= (\x -> head)))
                    ) "abc"

run $ enum (Cont (\e ->((step e) >>= (\x -> head)))
                    ) "abc"

-- enum feeds element to the iteratee, when it is Cont
run $ enum ((step (El 'a')) >>= (\x -> head)))
                    ) "bc"

-- As the step is from "drop 1", it is evaluated to "drop 1-1)"
run $ enum (drop (1-1) >>= (\x -> head)))
                    ) "bc"

run $ enum (drop 0 >>= (\x -> head)))
                    ) "bc"

run $ enum (Done () Empty >>= (\x -> head)))
                    ) "bc"

run $ enum (case ((\x -> head) () of 
                        Done x' _ -> Done x' Empty
                        Cont k     -> k Empty))
                    ) "bc"

run $ enum (case head of 
                        Done x' _ -> Done x' Empty
                        Cont k     -> k Empty))
                    ) "bc"

-- step is bound to head
run $ enum (case (Cont step) of 
                        Done x' _ -> Done x' Empty
                        Cont k     -> k Empty))
                    ) "bc"

run $ enum (step Empty) "bc"

-- This step is bound to head
run $ enum (Cont step) "bc"

run $ enum (Cont step) "bc"

run $ enum (step (El 'b')) "c"

-- Enum returns the iteratee if it is Done
run $ enum (Done (Just 'b') Empty) "c"

run $ (Done (Just 'b') Empty)

Just (Just 'b')