{-#LANGUAGE MultiParamTypeClasses #-} {-#LANGUAGE FlexibleContexts #-} {-#LANGUAGE FlexibleInstances #-} {-#LANGUAGE TypeOperators #-} {-#LANGUAGE RankNTypes #-} module Control.OOP.Base where -- | The instance-of typeclass. @a :> b@ means that @a@ is an instance of @b@. class a :> b where cast :: a -> b -- | Every interface is trivially an instance of itself. instance a :> a where cast = id -- | Member accessor: get an object member through an interface. member :: cls :> inst => (inst -> inst -> a) -> cls -> a member p obj = imember p (cast obj) imember :: (inst -> inst -> a) -> inst -> a imember p vt = p vt vt -- | Applicative accessor for a pure member. pureMember :: (cls :> inst, Applicative m) => (inst -> inst -> a) -> cls -> m a pureMember p = pure . member p -- | Accessing a pure member through a 'Functor' mapMember :: (cls :> inst, Functor m) => (inst -> inst -> a) -> m cls -> m a mapMember p = fmap (member p) -- | Flipped operator alias for 'member'. (-->) :: cls :> inst => cls -> (inst -> inst -> a) -> a (-->) = flip member infixl 8 --> -- | Flipped operator alias for 'imember'. (==>) :: inst -> (inst -> inst -> a) -> a (==>) = flip imember infixl 8 ==> -- | Flipped operator alias for 'pureMember'. (-->>) :: (cls :> inst, Applicative m) => cls -> (inst -> inst -> a) -> m a (-->>) = flip pureMember infixl 8 -->> -- | Flipped operator alias for 'mapMember'. (>-->) :: (cls :> inst, Functor m) => m cls -> (inst -> inst -> a) -> m a (>-->) = flip mapMember infixl 8 >-->