subhask-0.1.0.0: src/SubHask/Compatibility/Base.hs
{-# LANGUAGE NoRebindableSyntax #-}
-- | This file contains a LOT of instance declarations for making Base code compatible with SubHask type classes.
-- There's very little code in here though.
-- Most instances are generated using the functions in "SubHask.TemplateHaskell.Base".
module SubHask.Compatibility.Base
()
where
import Data.Typeable
import qualified Prelude as Base
import qualified Control.Applicative as Base
import qualified Control.Monad as Base
import Language.Haskell.TH
import Control.Arrow
import Control.Monad.Identity (Identity(..))
import Control.Monad.Reader (Reader,ReaderT)
import Control.Monad.State.Strict (State,StateT)
import Control.Monad.Trans
import Control.Monad.ST (ST)
import GHC.Conc.Sync
import GHC.GHCi
import Text.ParserCombinators.ReadP
import Text.ParserCombinators.ReadPrec
import Control.Monad.Random
import SubHask.Algebra
import SubHask.Category
import SubHask.Monad
import SubHask.Internal.Prelude
import SubHask.TemplateHaskell.Base
import SubHask.TemplateHaskell.Deriving
--------------------------------------------------------------------------------
-- bug fixes
-- required for GHCI to work because NoIO does not have a Base.Functor instance
instance Functor Hask NoIO where fmap = Base.liftM
-- these definitions are required for the corresponding types to be in scope in the TH code below;
-- pretty sure this is a GHC bug
dummy1 = undefined :: Identity a
dummy2 = undefined :: StateT s m a
dummy3 = undefined :: ReaderT s m a
--------------------------------------------------------------------------------
-- derive instances
-- forAllInScope ''Base.Eq mkPreludeEq
forAllInScope ''Base.Functor mkPreludeFunctor
-- forAllInScope ''Base.Applicative mkPreludeApplicative
forAllInScope ''Base.Monad mkPreludeMonad
--------------------------------------------------------------------------------
-- FIXME:
-- Similar instances are not valid for all monads.
-- For example, [] instance for Semigroup would be incompatible with the below definitions.
-- These instances are useful enough, however, that maybe we should have a template haskell generating function.
-- Possibly also a new type class that is a proof of compatibility.
mkMutable [t| forall a. IO a |]
instance Semigroup a => Semigroup (IO a) where
(+) = liftM2 (+)
instance Monoid a => Monoid (IO a) where
zero = return zero
--------------------------------------------------------------------------------
type instance Logic TypeRep = Bool
instance Eq_ TypeRep where
(==) = (Base.==)
instance POrd_ TypeRep where
inf x y = case Base.compare x y of
LT -> x
_ -> y
instance Lattice_ TypeRep where
sup x y = case Base.compare x y of
GT -> x
_ -> y
instance Ord_ TypeRep where compare = Base.compare
---------
mkMutable [t| forall a b. Either a b |]
instance (Semigroup b) => Semigroup (Either a b) where
(Left a) + _ = Left a
_ + (Left a) = Left a
(Right b1)+(Right b2) = Right $ b1+b2
instance (Monoid b) => Monoid (Either a b) where
zero = Right zero
---------
instance Base.Functor Maybe' where
fmap = fmap
instance Base.Applicative Maybe'
instance Base.Monad Maybe' where
return = Just'
Nothing' >>= f = Nothing'
(Just' a) >>= f = f a
instance Functor Hask Maybe' where
fmap f Nothing' = Nothing'
fmap f (Just' a) = Just' $ f a
instance Then Maybe' where
Nothing' >> _ = Nothing'
_ >> a = a
instance Monad Hask Maybe' where
return_ = Just'
join Nothing' = Nothing'
join (Just' Nothing') = Nothing'
join (Just' (Just' a)) = Just' a