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