License | BSD-3 |
---|---|
Maintainer | autotaker@gmail.com |
Stability | experimental |
Safe Haskell | None |
Language | Haskell2010 |
Synopsis
- class Typeable f => Label (f :: Type -> Type) where
- type InterfaceOf f
- toInterface :: (forall m. (Typeable m, Method m, MonadIO (Base m), Show (Args m)) => f m -> m) -> InterfaceOf f
- showLabel :: f m -> String
- compareLabel :: f m1 -> f m2 -> Ordering
- data (f :|: g) a
- deriveLabel :: Name -> DecsQ
Documentation
class Typeable f => Label (f :: Type -> Type) where Source #
Type class that represents f
denotes the type of field names of InterfaceOf f
type InterfaceOf f Source #
Interface type corrensponding to f
toInterface :: (forall m. (Typeable m, Method m, MonadIO (Base m), Show (Args m)) => f m -> m) -> InterfaceOf f Source #
Construct a interface from polymorphic function that returns each field of the interface.
showLabel :: f m -> String Source #
compareLabel :: f m1 -> f m2 -> Ordering Source #
f :|: g
is the disjoint union of label f
and label g
.
Use this type when you want to specify a protocol for multiple interfaces.
Example
data FooService = FooService { foo :: Int -> IO Bool, ... } data BarService = BarService { bar :: String -> IO (), ... } deriveLabel ''FooService deriveLabel ''BarService proto :: ProtocolM (FooServiceLabel:|:
BarServiceLabel) () proto = do i1 <- decl $ whenArgs (L
Foo) (==1) `thenReturn` True void $ decl $ whenArgs (R
Bar) (=="bar") `thenReturn` () `dependsOn` [i1] main :: IO () main = withProtocol proto $ \(fooService, barService) -> do ...
Instances
(Label f, Label g) => Label (f :|: g) Source # | |
Defined in Test.Method.Label type InterfaceOf (f :|: g) Source # | |
(Eq (f a), Eq (g a)) => Eq ((f :|: g) a) Source # | |
(Ord (f a), Ord (g a)) => Ord ((f :|: g) a) Source # | |
Defined in Test.Method.Label | |
(Show (f a), Show (g a)) => Show ((f :|: g) a) Source # | |
type InterfaceOf (f :|: g) Source # | |
Defined in Test.Method.Label |
deriveLabel :: Name -> DecsQ Source #
Generate the label type from given interface type.
Define GADT
XXXLabel m
for interfaceXXX
.FieldX :: XXXLabel X
for each fieldfieldX :: X
whereX
is a standard type.PolyFieldX :: XXXLabel ty[Dynamic/a]
for each field of the formpolyFieldX :: (forall a. Typeable a => ty)
- Define instance
Label XXXLabel
.
Example
data API env = API { _foo :: Int -> RIO env Int, _bar :: forall a. (Show a, Typeable a) => String -> RIO env (Maybe a), _baz :: forall b. (Typeable a) => b -> RIO env () }
deriveLabel ''API
will generate the following code.
data APILabel env m where Foo :: APILabel env (Int -> RIO env Int) Bar :: APILabel env (String -> RIO env (Maybe DynamicShow)) -- type variable `a` is replaced withDynamicShow
Baz :: APILabel env (Dynamic -> RIO env ()) -- type variable 'b' is replaced withDynamic
instance Label (APILabel env) where type InterfaceOf (APILabel env) = API env toInterface k = API (k Foo) (castMethod (k Bar)) (castMethod (k Baz)) showLabel x = case x of Foo -> Foo Bar -> Bar Baz -> Baz