[Haskell-beginners] Help with enumerator pipeline

David McBride dmcbride at neondsl.com
Thu Sep 1 00:03:19 CEST 2011


I wanted to solve this but the only way I could get it to compile was:

run_ ((((((enumHandle undefined undefined $= splitLines) $= parseLine)
$= filterObjects undefined) $= restrictObjects undefined) $= encoder)
$$ output)

This looks terrible, and I'm sure there is a better way, but I can't
find it.  If you remove any of the parenthesis it complains.  I would
love to heard the "right" way to do this.


On Wed, Aug 31, 2011 at 3:40 PM, Michael Xavier <nemesisdesign at gmail.com> wrote:
> I've just recently started learning how to use the enumerator library. I'm
> designing a utility that parses a file where each line is a JSON object.
> I've designed it to look like:
> source enumerator (enumHandle pretty much) ->
> chunk by lines (enumeratee) ->
> parse a line into an Object (enumeratee) ->
> filter objects based on a criteria (enumeratee) ->
> limit some keys from each object (enumeratee) ->
> encode the object into a lazy bytestring (enumeratee) ->
> output the file to stdout (iteratee)
> I'm having difficulties with the types, particularly composing the
> enumeratees in the middle. Someone in #haskell said that's a good case for
>>=> from Control.Monad but that seems to not like it if an enumeratee
> changes the type between the input and output.
> Here's the relevant types:
> type Object = Map Text Value
> pipeline :: MonadIO m => (Enumerator ByteString IO ()) -> [Text] -> [Filter]
> -> Iteratee a m ()
> pipeline s rfs fs = s $$ splitLines    >=>
>                          parseLine            >=>
>                          (filterObjects fs)   >=>
>                          (restrictFields rfs) >=>
>                          encoder              $$
>                          output
> splitLines :: Monad m => Enumeratee ByteString ByteString m b
> parseLine :: Monad m => Enumeratee ByteString Object m b
> filterObjects :: Monad m => [Filter] -> Enumeratee Object Object m b
> restrictObjects :: Monad m => [Text] -> Enumeratee Object Object m b
> encoder :: Monad m => Enumeratee Object LBS.ByteString m b
> output :: MonadIO m => Iteratee LBS.ByteString m ()
> I'm using >=> because I'd prefer to compose them left-right for readability
> Here's the error I get
>
>  Couldn't match expected type `ByteString'
>                 with actual type `M.Map Text Value'
>     Expected type: Data.Enumerator.Step ByteString m b1
>                    -> Iteratee ByteString m b2
>       Actual type: Enumeratee ByteString Object m0 b0
>     In the first argument of `(>=>)', namely `parseLine'
>     In the second argument of `(>=>)', namely
>       `parseLine
>      >=> (filterObjects fs) >=> (restrictFields rfs) >=> encoder'
> Any ideas?
> --
> Michael Xavier
> http://www.michaelxavier.net
> LinkedIn
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
>



More information about the Beginners mailing list