Created
May 15, 2016 19:11
-
-
Save sharkdp/aaf98bc4427fae6c65fa2050a38cb18e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE DeriveFunctor #-} | |
import Data.Monoid | |
import Control.Monad | |
import Control.Applicative | |
-- | An applicative functor `f` over a base type `b` that is "annotated" by a | |
-- | monoidal type `a`. | |
data Ann a f b = Ann a (f b) | |
deriving (Eq, Ord, Show, Functor) | |
instance (Monoid a, Applicative f) => Applicative (Ann a f) where | |
pure x = Ann mempty (pure x) | |
(Ann a1 f1) <*> (Ann a2 f2) = Ann (a1 <> a2) (f1 <*> f2) | |
-- | Extract the monoidal part of the annotated functor | |
annotation :: Ann a f b -> a | |
annotation (Ann a _) = a | |
-- | Extract the functorial part of the annotated functor | |
content :: Ann a f b -> f b | |
content (Ann _ fb) = fb | |
-- | Append a monoidal value to the annotated functor | |
annotate :: Monoid a => Ann a f b -> a -> Ann a f b | |
annotate (Ann a1 f) a2 = Ann (a1 <> a2) f | |
main :: IO () | |
main = do | |
let | |
x = pure 3 `annotate` ["Defining x"] | |
y = pure 5 `annotate` ["Defining y"] | |
z = liftA2 (*) x y `annotate` ["Multiplying"] | |
print $ content z == Just 15 | |
print $ annotation z == ["Defining x", "Defining y", "Multiplying"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment