Applicative.dcl 1.85 KB
Newer Older
Jurriën Stutterheim's avatar
Jurriën Stutterheim committed
1 2
definition module Control.Applicative

3
from Control.Monad import class Monad, class MonadPlus
4 5
from Data.Functor  import class Functor
from Data.Maybe    import :: Maybe
6
from Data.Monoid   import class Monoid, class Semigroup
7 8 9 10

:: Const a b = Const a
:: WrappedMonad m a = WrapMonad (m a)

11
unwrapMonad :: !(WrappedMonad m a) -> m a
12

13
getConst :: !(Const a b) -> a
Jurriën Stutterheim's avatar
Jurriën Stutterheim committed
14

Camil Staps's avatar
Camil Staps committed
15 16 17 18 19
class Applicative f | Functor f
where
	pure           :: a -> f a
	(<*>) infixl 4 :: !(f (a -> b)) (f a) -> f b

20 21 22 23 24 25
	(<*) infixl 4  :: !(f a) (f b) -> f a
	(<*) fa fb = pure (\x _->x) <*> fa <*> fb

	(*>) infixl 4  :: !(f a) (f b) -> f b
	(*>) fa fb = pure (\_ x->x) <*> fa <*> fb

Camil Staps's avatar
Camil Staps committed
26 27 28 29 30
class Alternative f | Applicative f
where
	empty          :: f a
	(<|>) infixl 3 :: !(f a) (f a) -> f a

31 32
instance Functor (Const m)
instance Functor (WrappedMonad m) | Monad m
33
instance Applicative (Const m) | Monoid m
34 35
instance Applicative (WrappedMonad m) | Monad m
instance Monad (WrappedMonad m) | Monad m
36

37 38
instance Alternative (WrappedMonad m) | MonadPlus m

39 40 41
instance Semigroup (Const a b) | Semigroup a
instance Monoid (Const a b) | Monoid a

Jurriën Stutterheim's avatar
Jurriën Stutterheim committed
42 43 44 45 46 47
some :: (f a) -> f [a] | Alternative f

many :: (f a) -> f [a] | Alternative f

(<**>) infixl 4 :: (f a) (f (a -> b)) -> f b | Applicative f

48 49
lift :: a -> f a | Applicative f

Jurriën Stutterheim's avatar
Jurriën Stutterheim committed
50 51 52 53 54 55 56
liftA :: (a -> b) (f a) -> f b | Applicative f

liftA2 :: (a b -> c) (f a) (f b) -> f c | Applicative f

liftA3 :: (a b c -> d) (f a) (f b) (f c) -> f d | Applicative f

optional :: (f a) -> f (Maybe a) | Alternative f
57 58 59 60 61 62 63

/**
 * Conditional execution of Applicative expressions. For example,
 *
 *     when debug (putStrLn "Debugging")
 *
 * will output the string Debugging if the Boolean value debug is True, and otherwise do nothing.
64 65
 *
 * @type Bool (f ()) -> f () | Applicative f
66 67 68 69 70
 */
when p s :== if p s (pure ())

/**
 * The reverse of `when`
71
 * @type Bool (f ()) -> f () | Applicative f
72 73
 */
unless p s :== if p (pure ()) s