How to define apply in terms of bind? - haskell

In Haskell Applicatives are considered stronger than Functor that means we can define Functor using Applicative like
-- Functor
fmap :: (a -> b) -> f a -> f b
fmap f fa = pure f <*> fa
and Monads are considered stronger than Applicatives & Functors that means.
-- Functor
fmap :: (a -> b) -> f a -> f b
fmap f fa = fa >>= return . f
-- Applicative
pure :: a -> f a
pure = return
(<*>) :: f (a -> b) -> f a -> f b
(<*>) = ??? -- Can we define this in terms return & bind? without using "ap"
I have read that Monads are for sequencing actions. But I feel like the only thing a Monad can do is Join or Flatten and the rest of its capabilities comes from Applicatives.
join :: m (m a) -> m a
-- & where is the sequencing in this part? I don't get it.
If Monad is really for sequencing actions then How come we can define Applicatives (which are not considered to strictly operate in sequence, some kind of parallel computing)?
As monads are Monoids in the Category of endofunctors. There are Commutative monoids as well, which necessarily need not work in order. That means the Monad instances for Commutative Monoids also need an ordering?
Edit:
I found an excellent page
http://wiki.haskell.org/What_a_Monad_is_not

If Monad is really for sequencing actions then How come we can define Applicatives (which are not considered to strictly operate in sequence, some kind of parallel computing)?
Not quite. All monads are applicatives, but only some applicatives are monads. So given a monad you can always define an applicative instance in terms of bind and return, but if all you have is the applicative instance then you cannot define a monad without more information.
The applicative instance for a monad would look like this:
instance (Monad m) => Applicative m where
pure = return
f <*> v = do
f' <- f
v' <- v
return $ f' v'
Of course this evaluates f and v in sequence, because its a monad and that is what monads do. If this applicative does not do things in a sequence then it isn't a monad.
Modern Haskell, of course, defines this the other way around: the Applicative typeclass is a subset of Functor so if you have a Functor and you can define (<*>) then you can create an Applicative instance. Monad is in turn defined as a subset of Applicative, so if you have an Applicative instance and you can define (>>=) then you can create a Monad instance. But you can't define (>>=) in terms of (<*>).
See the Typeclassopedia for more details.

We can copy the definition of ap and desugar it:
ap f a = do
xf <- f
xa <- a
return (xf xa)
Hence,
f <*> a = f >>= (\xf -> a >>= (\xa -> return (xf xa)))
(A few redundant parentheses added for clarity.)

(<*>) :: f (a -> b) -> f a -> f b
(<*>) = ??? -- Can we define this in terms return & bind? without using "ap"
Recall that <*> has the type signature of f (a -> b) -> f a -> f b, and >>= has m a -> (a -> m b) -> m b. So how can we infer m (a -> b) -> m a -> m b from m a -> (a -> m b) -> m b?
To define f <*> x with >>=, the first parameter of >>= should be f obviously, so we can write the first transformation:
f <*> x = f >>= k -- k to be defined
where the function k takes as a parameter a function with the type of a -> b, and returns a result of m b such that the whole definition aligns with the type signature of bind >>=. For k, we can write:
k :: (a -> b) -> m b
k = \xf -> h x
Note that the function h should use x from f <*> x since x is related to the result of m b in some way like the function xf of a -> b.
For h x, it's easy to get:
h :: m a -> m b
h x = x >>= return . xf
Put the above three definations together, and we get:
f <*> x = f >>= \xf -> x >>= return . xf
So even though you don't know the defination of ap, you can still get the final result as shown by #chi according to the type signature.

Related

Does the Applicative interface provide power beyond the ability to lift multi-argument functions (in curried form) into a Functor?

Applicatives are often presented as a way to lift multi-argument functions
into a functor and apply functor values to it. But I wonder if there is some
subtle additional power stemming from the fact that it can do so by lifting
functions that return a function and applying the function arguments one at
a time.
Imagine instead we define an interface based on lifting functions whose argument is a tuple of arguments:
# from Functor
fmap :: (a -> b) -> Fa -> Fb
# from Applicative
pure :: a -> Fa
# combine multiple functor values into a functor of a tuple
tuple1 :: Fa -> F(a)
tuple2 :: Fa -> Fb -> F(a,b)
tuple3 :: Fa -> Fb -> Fc -> F(a,b,c)
(etc ...)
# lift multi-argument functions (that take a tuple as input)
ap_tuple1 :: ((a) -> b) -> F(a) -> Fb
ap_tuple2 :: ((a,b) -> c) -> F(a,b) -> Fc
ap_tuple3 :: ((a,b,c) -> d) -> F(a,b,c) -> Fd
(etc ..)
Assume we had the corresponding tuple function defined for every sized tuple we may encounter.
Would this interface be equally as powerful as the Applicative interface, given it allows for
lifting/applying-to multi-argument functions BUT doesn't allow for lifting/applying-to functions
that return a function? Obviously one can curry functions that take a tuple as an argument
so they can be lifted in an applicative and one can uncurry functions that return a function
in order to lift them into hypothetical implementation above. But to my mind there is a subtle
difference in power. Is there any difference? (Assuming the question even makes sense)
You've rediscovered the monoidal presentation of Applicative. It looks like this:
class Functor f => Monoidal f where
(>*<) :: f a -> f b -> f (a, b)
unit :: f ()
It's isomorphic to Applicative via:
(>*<) = liftA2 (,)
unit = pure ()
pure x = x <$ unit
f <*> x = fmap (uncurry ($)) (f >*< x)
By the way, your ap_tuple functions are all just fmap. The "hard" part with multiple values is combining them together. Splitting them back into pieces is "easy".
Yes, this is equally as powerful. Notice that pure and tuple1 are the same. Further, everything higher than tuple2 is recovered from tuple2 and fmap:
tuple3 x y z = repair <$> tuple2 (tuple2 x y) z
where repair ((a, b), c) = (a, b, c)
tuple4 w x y z = repair <$> tuple2 (tuple2 x y) (tuple2 x y)
where repair ((a, b), (c, d)) = (a, b, c, d)
-- etc.
Also, all of the ap_tuples are just fmap:
ap_tuple1 = fmap
ap_tuple2 = fmap
ap_tuple3 = fmap
-- ...
Renaming prod = tuple2, your question boils down to
Is
class Functor f => Applicative f where
pure :: a -> f a
prod :: f a -> f b -> f (a, b)
equivalent to
class Functor f => Applicative f where
pure :: a -> f a
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
?
And you might already see that the answer is yes. prod is just a specialization of liftA2
prod = liftA2 (,)
But (,) is "natural" in the sense that it doesn't "delete" anything, so you can recover liftA2 just by destructuring the data back out:
liftA2 f x y = f' <$> prod x y
where f' (a, b) = f a b

How can I show that `Monad` is actually `Applicative` and `Functor`?

In Haskell, class Monad is declared as:
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
return = pure
How can I show that Monad is actually Applicative, which is declared like this?
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Specifically, how can I write pure and <*> in terms of return and >>=?
How can I show that Monad is actually Functor, which is declared like this?
class Functor f where
fmap :: (a -> b) -> f a -> f b
Specifically, how can I write fmap in terms of return and >>=?
These are all in the documentation.
Specifically, how can I write pure and <*> in terms of return and >>=?
See http://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Monad.html#t:Monad, specifically this section:
Furthermore, the Monad and Applicative operations should relate as follows:
pure = return
(<*>) = ap
and note that ap was a standard Monad function long before Applicative was introduced as a standard part of the language, and is defined as ap m1 m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) }
Specifically, how can I write fmap in terms of return and >>=?
The Control.Applicative documentation says:
As a consequence of these laws, the Functor instance for f will satisfy
fmap f x = pure f <*> x
Which of course, using what I quoted above, you can use to implement fmap in terms of return and >>=.
And as #duplode points out, there are also liftM for Monads, and liftA for Applicatives, which are (essentially, although they're not defined literally that way) synonyms of fmap, specialised to their particular type classes.

Is the streaming package's Stream data type equivalent to FreeT?

The streaming package defines a Stream type that looks like the following:
data Stream f m r
= Step !(f (Stream f m r))
| Effect (m (Stream f m r))
| Return r
There is a comment on the Stream type that says the following:
The Stream data type is equivalent to FreeT and can represent any effectful succession of steps, where the form of the steps or 'commands' is specified by the first (functor) parameter.
I'm wondering how the Stream type is equivalent to FreeT?
Here is the definition of FreeT:
data FreeF f a b = Pure a | Free (f b)
newtype FreeT f m a = FreeT { runFreeT :: m (FreeF f a (FreeT f m a)) }
It looks like it is not possible to create an isomorphism between these two types.
To be specific, I don't see a way to write the following two functions that makes them an isomorphism:
freeTToStream :: FreeT f m a -> Stream f m a
streamToFreeT :: Stream f m a -> FreeT f m a
For instance, I'm not sure how to express a value like Return "hello" :: Stream f m String as a FreeT.
I guess it could be done like the following, but the Pure "hello" is necessarily going to be wrapped in an m, while in Return "hello" :: Stream f m String it is not:
FreeT $ pure $ Pure "hello" :: Applicative m => FreeT f m a
Can Stream be considered equivalent to FreeT even though it doesn't appear possible to create an isomorphism between them?
There are some small differences that make them not literally equivalent. In particular, FreeT enforces an alternation of f and m,
FreeT f m a = m (Either a (f (FreeT f m a) = m (Either a (f (m (...))))
-- m f m -- alternating
whereas Stream allows stuttering, e.g., we can construct the following with no Step between two Effect:
Effect (return (Effect (return (Return r))))
which should be equivalent in some sense to
Return r
Thus we shall take a quotient of Stream by the following equations that flatten the layers of Effect:
Effect (m >>= \a -> return (Effect (k a))) = Effect (m >>= k)
Effect (return x) = x
Under that quotient, the following are isomorphisms
freeT_stream :: (Functor f, Monad m) => FreeT f m a -> Stream f m a
freeT_stream (FreeT m) = Effect (m >>= \case
Pure r -> return (Return r)
Free f -> return (Step (fmap freeT_stream f))
stream_freeT :: (Functor f, Monad m) => Stream f m a -> FreeT f m a
stream_freeT = FreeT . go where
go = \case
Step f -> return (Free (fmap stream_freeT f))
Effect m -> m >>= go
Return r -> return (Pure r)
Note the go loop to flatten multiple Effect constructors.
Pseudoproof: (freeT_stream . stream_freeT) = id
We proceed by induction on a stream x. To be honest, I'm pulling the induction hypotheses out of thin air. There are certainly cases where induction is not applicable. It depends on what m and f are, and there might also be some nontrivial setup to ensure this approach makes sense for a quotient type. But there should still be many concrete m and f where this scheme is applicable. I hope there is some categorical interpretation that translates this pseudoproof to something meaningful.
(freeT_stream . stream_freeT) x
= freeT_stream (FreeT (go x))
= Effect (go x >>= \case
Pure r -> return (Return r)
Free f -> return (Step (fmap freeT_stream f)))
Case x = Step f, induction hypothesis (IH) fmap (freeT_stream . stream_freeT) f = f:
= Effect (return (Step (fmap freeT_stream (fmap stream_freeT f))))
= Effect (return (Step f)) -- by IH
= Step f -- by quotient
Case x = Return r
= Effect (return (Return r))
= Return r -- by quotient
Case x = Effect m, induction hypothesis m >>= (return . freeT_stream . stream_freeT)) = m
= Effect ((m >>= go) >>= \case ...)
= Effect (m >>= \x' -> go x' >>= \case ...) -- monad law
= Effect (m >>= \x' -> return (Effect (go x' >>= \case ...))) -- by quotient
= Effect (m >>= \x' -> (return . freeT_stream . stream_freeT) x') -- by the first two equations above in reverse
= Effect m -- by IH
Converse left as an exercise.
Both your example with Return and my example with nested Effect constructors cannot be represented by FreeT with the same parameters f and m. There are more counterexamples, too. The underlying difference in the data types can best be seen in a hand-wavey space where the data constructors are stripped out and infinite types are allowed.
Both Stream f m a and FreeT f m a are for nesting an a type inside a bunch of f and m type constructors. Stream allows arbitrary nesting of f and m, while FreeT is more rigid. It always has an outer m. That contains either an f and another m and repeats, or an a and terminates.
But that doesn't mean there isn't an equivalence of some sort between the types. You can show some equivalence by showing that each type can be embedded inside the other faithfully.
Embedding a Stream inside a FreeT can be done on the back of one observation: if you choose an f' and m' such that the f and m type constructors are optional at each level, you can model arbitrary nesting of f and m. One quick way to do that is use Data.Functor.Sum, then write a function:
streamToFreeT :: Stream f m a -> FreeT (Sum Identity f) (Sum Identity m) a
streamToFreeT = undefined -- don't have a compiler nearby, not going to even try
Note that the type won't have the necessary instances to function. That could be corrected by switching Sum Identity to a more direct type that actually has an appropriate Monad instance.
The transformation back the other direction doesn't need any type-changing trickery. The more restricted shape of FreeT is already directly embeddable inside Stream.
I'd say this makes the documentation correct, though possibly it should use a more precise term than "equivalent". Anything you can construct with one type, you can construct with the other - but there might be some extra interpretation of the embedding and a change of variables involved.

How to map over Applicative form?

I want to map over Applicative form.
The type of map-like function would be like below:
mapX :: (Applicative f) => (f a -> f b) -> f [a] -> f [b]
used as:
result :: (Applicative f) => f [b]
result = mapX f xs
where f :: f a -> f b
f = ...
xs :: f[a]
xs = ...
As the background of this post, I try to write fluid simulation program using Applicative style referring to Paul Haduk's "The Haskell School of Expression", and I want to express the simulation with Applicative style as below:
x, v, a :: Sim VArray
x = x0 +: integral (v * dt)
v = v0 +: integral (a * dt)
a = (...calculate acceleration with x v...)
instance Applicative Sim where
...
where Sim type means the process of simulation computation and VArray means Array of Vector (x,y,z). X, v a are the arrays of position, velocity and acceleration, respectively.
Mapping over Applicative form comes when definining a.
I've found one answer to my question.
After all, my question is "How to lift high-order functions (like map
:: (a -> b) -> [a] -> [b]) to the Applicative world?" and the answer
I've found is "To build them using lifted first-order functions."
For example, the "mapX" is defined with lifted first-order functions
(headA, tailA, consA, nullA, condA) as below:
mapX :: (f a -> f b) -> f [a] -> f [b]
mapX f xs0 = condA (nullA xs0) (pure []) (consA (f x) (mapA f xs))
where
x = headA xs0
xs = tailA xs0
headA = liftA head
tailA = liftA tail
consA = liftA2 (:)
nullA = liftA null
condA b t e = liftA3 aux b t e
where aux b t e = if b then t else e
First, I don't think your proposed type signature makes much sense. Given an applicative list f [a] there's no general way to turn that into [f a] -- so there's no need for a function of type f a -> f b. For the sake of sanity, we'll reduce that function to a -> f b (to transform that into the other is trivial, but only if f is a monad).
So now we want:
mapX :: (Applicative f) => (a -> f b) -> f [a] -> f [b]
What immediately comes to mind now is traverse which is a generalization of mapM. Traverse, specialized to lists:
traverse :: (Applicative f) => (a -> f b) -> [a] -> f [b]
Close, but no cigar. Again, we can lift traverse to the required type signature, but this requires a monad constraint: mapX f xs = xs >>= traverse f.
If you don't mind the monad constraint, this is fine (and in fact you can do it more straightforwardly just with mapM). If you need to restrict yourself to applicative, then this should be enough to illustrate why you proposed signature isn't really possible.
Edit: based on further information, here's how I'd start to tackle the underlying problem.
-- your sketch
a = liftA sum $ mapX aux $ liftA2 neighbors (x!i) nbr
where aux :: f Int -> f Vector3
-- the type of "liftA2 neighbors (x!i) nbr" is "f [Int]
-- my interpretation
a = liftA2 aux x v
where
aux :: VArray -> VArray -> VArray
aux xi vi = ...
If you can't write aux like that -- as a pure function from the positions and velocities at one point in time to the accelerations, then you have bigger problems...
Here's an intuitive sketch as to why. The stream applicative functor takes a value and lifts it into a value over time -- a sequence or stream of values. If you have access to a value over time, you can derive properties of it. So velocity can be defined in terms of acceleration, position can be defined in terms of velocity, and soforth. Great! But now you want to define acceleration in terms of position and velocity. Also great! But you should not need, in this instance, to define acceleration in terms of velocity over time. Why, you may ask? Because velocity over time is all acceleration is to begin with. So if you define a in terms of dv, and v in terms of integral(a) then you've got a closed loop, and your equations are not propertly determined -- either there are, even given initial conditions, infinitely many solutions, or there are no solutions at all.
If I'm thinking about this right, you can't do this just with an applicative functor; you'll need a monad. If you have an Applicative—call it f—you have the following three functions available to you:
fmap :: (a -> b) -> f a -> f b
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
So, given some f :: f a -> f b, what can you do with it? Well, if you have some xs :: [a], then you can map it across: map (f . pure) xs :: [f b]. And if you instead have fxs :: f [a], then you could instead do fmap (map (f . pure)) fxs :: f [f b].1 However, you're stuck at this point. You want some function of type [f b] -> f [b], and possibly a function of type f (f b) -> f b; however, you can't define these on applicative functors (edit: actually, you can define the former; see the edit). Why? Well, if you look at fmap, pure, and <*>, you'll see that you have no way to get rid of (or rearrange) the f type constructor, so once you have [f a], you're stuck in that form.
Luckily, this is what monads are for: computations which can "change shape", so to speak. If you have a monad m, then in addition to the above, you get two extra methods (and return as a synonym for pure):
(>>=) :: m a -> (a -> m b) -> m b
join :: m (m a) -> m a
While join is only defined in Control.Monad, it's just as fundamental as >>=, and can sometimes be clearer to think about. Now we have the ability to define your [m b] -> m [b] function, or your m (m b) -> m b. The latter one is just join; and the former is sequence, from the Prelude. So, with monad m, you can define your mapX as
mapX :: Monad m => (m a -> m b) -> m [a] -> m [b]
mapX f mxs = mxs >>= sequence . map (f . return)
However, this would be an odd way to define it. There are a couple of other useful functions on monads in the prelude: mapM :: Monad m => (a -> m b) -> [a] -> m [b], which is equivalent to mapM f = sequence . map f; and (=<<) :: (a -> m b) -> m a -> m b, which is equivalent to flip (>>=). Using those, I'd probably define mapX as
mapX :: Monad m => (m a -> m b) -> m [a] -> m [b]
mapX f mxs = mapM (f . return) =<< mxs
Edit: Actually, my mistake: as John L kindly pointed out in a comment, Data.Traversable (which is a base package) supplies the function sequenceA :: (Applicative f, Traversable t) => t (f a) => f (t a); and since [] is an instance of Traversable, you can sequence an applicative functor. Nevertheless, your type signature still requires join or =<<, so you're still stuck. I would probably suggest rethinking your design; I think sclv probably has the right idea.
1: Or map (f . pure) <$> fxs, using the <$> synonym for fmap from Control.Applicative.
Here is a session in ghci where I define mapX the way you wanted it.
Prelude>
Prelude> import Control.Applicative
Prelude Control.Applicative> :t pure
pure :: Applicative f => a -> f a
Prelude Control.Applicative> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Prelude Control.Applicative> let mapX fun ma = pure fun <*> ma
Prelude Control.Applicative> :t mapX
mapX :: Applicative f => (a -> b) -> f a -> f b
I must however add that fmap is better to use, since Functor is less expressive than Applicative (that means that using fmap will work more often).
Prelude> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
edit:
Oh, you have some other signature for mapX, anyway, you maybe meant the one I suggested (fmap)?

How to use (->) instances of Monad and confusion about (->)

At different questions I've found hints in comments concerning using the (->) instance of Monads e.g. for realizing point-free style.
As for me, this is a little too abstract. Ok, I've seen Arrow instances on (->) and it seems to me, that (->) can be used in instance notations but not in type declarations (that would alone be stuff for another question).
Has anyone examples using (->) as instance of Monad? Or a good link?
Sorry if this question may already have been discussed here, but searching for "(->) Monad instance" gives you many many hits as you can imagine ... since nearly every question about Haskell somewhere involves (->) or "Monad".
For a given type r, the function of type r -> a can be thought of as a computation delivering an a using an environment typed r. Given two functions r -> a and a -> (r -> b), it's easy to imagine that one can compose these when given an environment (again, of type r).
But wait! That's exactly what monads are about!
So we can create an instance of Monad for (->) r that implements f >>= g by passing the r to both f and g. This is what the Monad instance for (->) r does.
To actually access the environment, you can use id :: r -> r, which you can now think of as a computation running in an environment r and delivering an r. To create local sub-environments, you can use the following:
inLocalEnvironment :: (r -> r) -> (r -> a) -> (r -> a)
inLocalEnvironment xform f = \env -> f (xform env)
This pattern of having an environment passed to computations that can then query it and modify it locally is useful for not just the (->) r monad, which is why it is abstracted into the MonadReader class, using much more sensible names than what I've used here:
http://hackage.haskell.org/packages/archive/mtl/2.0.1.0/doc/html/Control-Monad-Reader-Class.html
Basically, it has two instances: (->) r that we've seen here, and ReaderT r m, which is just a newtype wrapper around r -> m a, so it's the same thing as the (->) r monad I've described here, except it delivers computations in some other, transformed monad.
To define a monad for (->) r, we need two operations, return and (>>=), subject to three laws:
instance Monad ((->) r) where
If we look at the signature of return for (->) r
return :: a -> r -> a
we can see its just the constant function, which ignores its second argument.
return a r = a
Or alternately,
return = const
To build (>>=), if we specialize its type signature with the monad (->) r,
(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b
there is really only one possible definition.
(>>=) x y z = y (x z) z
Using this monad is like passing along an extra argument r to every function. You might use this for configuration, or to pass options way down deep into the bowels of your program.
We can check that it is a monad, by verifying the three monad laws:
1. return a >>= f = f a
return a >>= f
= (\b -> a) >>= f -- by definition of return
= (\x y z -> y (x z) z) (\b -> a) f -- by definition of (>>=)
= (\y z -> y ((\b -> a) z) z) f -- beta reduction
= (\z -> f ((\b -> a) z) z) -- beta reduction
= (\z -> f a z) -- beta reduction
= f a -- eta reduction
2. m >>= return = m
m >>= return
= (\x y z -> y (x z) z) m return -- definition of (>>=)
= (\y z -> y (m z) z) return -- beta reduction
= (\z -> return (m z) z) -- beta reduction
= (\z -> const (m z) z) -- definition of return
= (\z -> m z) -- definition of const
= m -- eta reduction
The final monad law:
3. (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
follows by similar, easy equational reasoning.
We can define a number of other classes for ((->) r) as well, such as Functor,
instance Functor ((->) r) where
and if we look at the signature of
-- fmap :: (a -> b) -> (r -> a) -> r -> b
we can see that its just composition!
fmap = (.)
Similarly we can make an instance of Applicative
instance Applicative ((->) r) where
-- pure :: a -> r -> a
pure = const
-- (<*>) :: (r -> a -> b) -> (r -> a) -> r -> b
(<*>) g f r = g r (f r)
What is nice about having these instances is they let you employ all of the Monad and Applicative combinators when manipulating functions.
There are plenty of instances of classes involving (->), for instance, you could hand-write the instance of Monoid for (b -> a), given a Monoid on a as:
enter code here
instance Monoid a => Monoid (b -> a) where
-- mempty :: Monoid a => b -> a
mempty _ = mempty
-- mappend :: Monoid a => (b -> a) -> (b -> a) -> b -> a
mappend f g b = f b `mappend` g b
but given the Monad/Applicative instance, you can also define this instance with
instance Monoid a => Monoid (r -> a) where
mempty = pure mempty
mappend = liftA2 mappend
using the Applicative instance for (->) r or with
instance Monoid a => Monoid (r -> a) where
mempty = return mempty
mappend = liftM2 mappend
using the Monad instance for (->) r.
Here the savings are minimal, but, for instance the #pl tool for generating point-free code, which is provided by lambdabot on the #haskell IRC channel abuses these instances quite a bit.

Resources