suztomoの日記

To be a good software engineer

Evaluate iteratee: length

As I'm not clear about how iteratees work, here I write down the step of "length" iteratee.

length :: IterV el Int
length = Cont (step 0)
  where
    step acc (El _) = Cont (step (acc+1))
    step acc Empty = Cont (step acc)
    step acc EOF = Done acc EOF


enum :: IterV el a -> [el] -> IterV el a
enum i [] = i
enum i@(Done _ _) _ = i
enum (Cont k) (x:xs) = enum (k (El x)) xs

run :: IterV el a -> Maybe a
run (Done x _) = Just x
run (Cont k) = run' (k EOF)
 where
   run' (Done x _) = Just x
   run' _ = Nothing
*Main> run $ enum length "abc"
Just 3
-- as the first operation of run is pattern match, we have to evaluate the arguments
run $ enum length "abc"

-- as the first operation of enum is pattern match, we have to evaluate the arguments
run $ enum (Cont (step 0)) "abc"

-- Using the last equation of enum
run $ enum ((step 0) El 'a') "bc"

-- as the first operation of enum is pattern match, evaluate the first argument
-- Here, it discards the 'a'. Using the first rule of step.
run $enum (Cont (step (0+1))) "bc"

-- Continues...
run $ enum (step (0+1) (El 'b')) "c"  -- Using the last rule of enum

run $ enum (Cont (step (0+1+1))) "c" -- definition of step as we need pattern match for the first argument

run $ enum (step (0+1+1) (El 'c')) [] -- Using the last rule of enum
run $ enum (step (0+1+1) (El 'c')) [] -- Using the last rule of enum

run $ step (0+1+1) (El 'c') -- Using the first rule of enum. As we need pattern match against the first argument of run, we continue evaluate the right side of '$'

run $ Cont (step (0+1+1+1))   -- Using first rule of step

run' (step (0+1+1+1) EOF)    -- Using second rule of run

run' (Done (0+1+1+1) EOF)    -- The first argument of run' needs to be evaluated

Just (0+1+1+1) -- using the first rule of run'

Just 3 -- evaluate to output the result