summaryrefslogtreecommitdiff
path: root/lib/FunctorToMaybe.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2016-04-24 18:43:00 -0400
committerjoe <joe@jerkface.net>2016-04-24 18:43:00 -0400
commitfbf425fbef1c1e60fcdddfbd9b25976162725f97 (patch)
treeb3877b56401f22efed0486ae10950af3a5ebadf8 /lib/FunctorToMaybe.hs
parent7d8798f60b11973fd17d85caf3da2e8473842d2a (diff)
Refactored build of executable and library.
Diffstat (limited to 'lib/FunctorToMaybe.hs')
-rw-r--r--lib/FunctorToMaybe.hs69
1 files changed, 69 insertions, 0 deletions
diff --git a/lib/FunctorToMaybe.hs b/lib/FunctorToMaybe.hs
new file mode 100644
index 0000000..658b024
--- /dev/null
+++ b/lib/FunctorToMaybe.hs
@@ -0,0 +1,69 @@
1---------------------------------------------------------------------------
2-- |
3-- Module : FunctorToMaybe
4--
5-- Maintainer : joe@jerkface.net
6-- Stability : experimental
7--
8-- Motivation: When parsing a stream of events, it is often desirable to
9-- let certain control events pass-through to the output stream without
10-- interrupting the parse. For example, the conduit package uses
11-- <http://hackage.haskell.org/package/conduit-1.0.13.1/docs/Data-Conduit.html#t:Flush Flush>
12-- which adds a special command to a stream and the blaze-builder-conduit
13-- package has <http://hackage.haskell.org/package/blaze-builder-conduit-1.0.0/docs/Data-Conduit-Blaze.html#g:2 conduits> that treat the nullary constructor with special significance.
14--
15-- But for other intermediary conduits, the nullary @Flush@ constructor may
16-- be noise that they should politely preserve in case it is meaningul downstream.
17-- If <http://hackage.haskell.org/package/conduit-1.0.13.1/docs/Data-Conduit.html#t:Flush Flush>
18-- implemented the 'FunctorToMaybe' type class, then 'functorToEither' could be used to
19-- seperate the noise from the work-product.
20--
21{-# LANGUAGE CPP #-}
22module FunctorToMaybe where
23
24#if MIN_VERSION_base(4,6,0)
25#else
26import Control.Monad.Instances()
27#endif
28
29-- | The 'FunctorToMaybe' class genaralizes 'Maybe' in that the
30-- there may be multiple null elements.
31--
32-- Instances of 'FunctorToMaybe' should satisfy the following laws:
33--
34-- > functorToMaybe (fmap f g) == fmap f (functorToMaybe g)
35--
36class Functor g => FunctorToMaybe g where
37 functorToMaybe :: g a -> Maybe a
38
39
40instance FunctorToMaybe Maybe where
41 functorToMaybe = id
42instance FunctorToMaybe (Either a) where
43 functorToMaybe (Right x) = Just x
44 functorToMaybe _ = Nothing
45
46
47-- | 'functorToEither' is a null-preserving cast.
48--
49-- If @functorToMaybe g == Nothing@, then a casted value is returned with Left.
50-- If @functorToMaybe g == Just a@, then @Right a@ is returned.
51--
52-- Returning to our <http://hackage.haskell.org/package/conduit-1.0.13.1/docs/Data-Conduit.html#t:Flush Flush>
53-- example, if we define
54--
55-- > instance Flush where
56-- > functorToMaybe Flush = Nothing
57-- > functorToMaybe (Chunk a) = Just a
58--
59-- Now stream processors can use 'functorToEither' to transform any nullary constructors while
60-- while doing its work to transform the data before forwarding it into
61-- <http://hackage.haskell.org/package/blaze-builder-conduit-1.0.0/docs/Data-Conduit-Blaze.html#v:builderToByteStringFlush builderToByteStringFlush>.
62--
63functorToEither :: FunctorToMaybe f => f a -> Either (f b) a
64functorToEither ga =
65 maybe (Left $ uncast ga)
66 Right
67 (functorToMaybe ga)
68 where
69 uncast = fmap (error "bad FunctorToMaybe instance")