module Dep.Phases ( -- * Qualified do-notation for building phases -- $warning (>>=), (>>), -- * Re-exports Compose (..), ) where import Data.Functor.Compose import Prelude (Functor, (<$>), (<$)) (>>=) :: Functor f => f x -> (x -> g y) -> Compose f g y f x f >>= :: forall (f :: * -> *) x (g :: * -> *) y. Functor f => f x -> (x -> g y) -> Compose f g y >>= x -> g y k = forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1). f (g a) -> Compose f g a Compose (x -> g y k forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> f x f) (>>) :: Functor f => f x -> g y -> Compose f g y f x f >> :: forall (f :: * -> *) x (g :: * -> *) y. Functor f => f x -> g y -> Compose f g y >> g y g = forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1). f (g a) -> Compose f g a Compose (g y g forall (f :: * -> *) a b. Functor f => a -> f b -> f a <$ f x f) -- $warning -- Convenient [qualified -- do-notation](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/qualified_do.html#extension-QualifiedDo) -- for defining nested applicative phases wrapped in 'Compose's. -- -- __BEWARE__! Despite its convenience, this do-notation lacks [many of the properties](https://wiki.haskell.org/Monad_laws#The_monad_laws_in_practice) -- we tend to assume when working with do-notation. In particular, it's -- NOT associative! This means that if we have -- -- @ -- Dep.Phases.do -- somePhase -- someOtherPhase -- finalPhase -- @ -- -- we CAN'T refactor to -- -- @ -- Dep.Phases.do -- Dep.Phases.do -- somePhase -- someOtherPhase -- finalPhase -- @ -- -- It would indeed be useful (it would allow pre-packaging and sharing initial -- phases as do-blocks) but it isn't supported. -- -- __BEWARE__ #2! Do not use 'return' in this do-notation. -- -- Some valid examples: -- -- >>> :{ -- type Phases = (IO `Compose` IO `Compose` IO) Int -- phases :: Phases -- phases = Dep.Phases.do -- r1 <- pure 1 -- r2 <- pure 2 -- pure $ r1 + r2 -- :} -- -- -- >>> :{ -- type Phases = (IO `Compose` Maybe `Compose` Either Char) Int -- phases :: Phases -- phases = Dep.Phases.do -- pure () -- Just 5 -- Left 'e' -- :} -- -- -- $setup -- -- >>> :set -XTypeApplications -- >>> :set -XMultiParamTypeClasses -- >>> :set -XImportQualifiedPost -- >>> :set -XStandaloneKindSignatures -- >>> :set -XNamedFieldPuns -- >>> :set -XFunctionalDependencies -- >>> :set -XFlexibleContexts -- >>> :set -XDataKinds -- >>> :set -XBlockArguments -- >>> :set -XFlexibleInstances -- >>> :set -XTypeFamilies -- >>> :set -XDeriveGeneric -- >>> :set -XViewPatterns -- >>> :set -XDerivingStrategies -- >>> :set -XDerivingVia -- >>> :set -XDeriveAnyClass -- >>> :set -XStandaloneDeriving -- >>> :set -XUndecidableInstances -- >>> :set -XTypeOperators -- >>> :set -XScopedTypeVariables -- >>> :set -XQualifiedDo -- >>> :set -fno-warn-deprecations -- >>> import Data.Kind -- >>> import Data.Function ((&)) -- >>> import Dep.Env -- >>> import GHC.Generics (Generic) -- >>> import Prelude hiding ((>>=), (>>))