--------------------------------------------------------------------------- -- | -- Module : FunctorToMaybe -- -- Maintainer : joe@jerkface.net -- Stability : experimental -- -- Motivation: When parsing a stream of events, it is often desirable to -- let certain control events pass-through to the output stream without -- interrupting the parse. For example, the conduit package uses -- -- which adds a special command to a stream and the blaze-builder-conduit -- package has that treat the nullary constructor with special significance. -- -- But for other intermediary conduits, the nullary @Flush@ constructor may -- be noise that they should politely preserve in case it is meaningul downstream. -- If -- implemented the 'FunctorToMaybe' type class, then 'functorToEither' could be used to -- seperate the noise from the work-product. -- module FunctorToMaybe where -- | The 'FunctorToMaybe' class genaralizes 'Maybe' in that the -- there may be multiple null elements. -- -- Instances of 'FunctorToMaybe' should satisfy the following laws: -- -- > functorToMaybe (fmap f g) == fmap f (functorToMaybe g) -- class Functor g => FunctorToMaybe g where functorToMaybe :: g a -> Maybe a instance FunctorToMaybe Maybe where functorToMaybe = id instance FunctorToMaybe (Either a) where functorToMaybe (Right x) = Just x functorToMaybe _ = Nothing -- | 'functorToEither' is a null-preserving cast. -- -- If @functorToMaybe g == Nothing@, then a casted value is returned with Left. -- If @functorToMaybe g == Just a@, then @Right a@ is returned. -- -- Returning to our -- example, if we define -- -- > instance FunctorToMaybe Flush where -- > functorToMaybe Flush = Nothing -- > functorToMaybe (Chunk a) = Just a -- -- Now stream processors can use 'functorToEither' to transform any nullary constructors while -- while doing its work to transform the data before forwarding it into -- . -- functorToEither :: FunctorToMaybe f => f a -> Either (f b) a functorToEither ga = maybe (Left $ uncast ga) Right (functorToMaybe ga) where uncast = fmap (error "bad FunctorToMaybe instance")