@@ -27,21 +27,41 @@ import Prelude.Compat
2727
2828import Servant.API
2929
30−class Enter typ arg ret | typ arg -> ret, typ ret -> arg where
31− enter :: arg -> typ -> ret
30+type family Entered m n api where
31+ Entered m n (m a) = n a
32+ Entered m n (a -> api) = a -> Entered m n api
33+ Entered m n (api1 :<|> api2) = Entered m n api1 :<|> Entered m n api2
34+
35+class ( Entered m n typ ~ ret
36+ , Entered n m ret ~ typ
37+ )
38+ => Enter typ m n ret
39+ where
40+ enter :: (m :~> n) -> typ -> ret
3241
3342-- ** Servant combinators
34−instance ( Enter typ1 arg1 ret1, Enter typ2 arg2 ret2
35− , arg1 ~ arg2
36− ) => Enter (typ1 :<|> typ2) arg1 (ret1 :<|> ret2) where
43+
44+instance
45+ ( Entered m1 n1 (typ1 :<|> typ2) ~ (ret1 :<|> ret2)
46+ , Entered n1 m1 (ret1 :<|> ret2) ~ (typ1 :<|> typ2)
47+ , Enter typ1 m1 n1 ret1, Enter typ2 m2 n2 ret2
48+ , m1 ~ m2, n1 ~ n2
49+ ) => Enter (typ1 :<|> typ2) m1 n1 (ret1 :<|> ret2)
50+ where
3751 enter e (a :<|> b) = enter e a :<|> enter e b
3852
39−instance (Enter b arg ret) => Enter (a -> b) arg (a -> ret) where
53+instance
54+ ( Entered m n (a -> typ) ~ (a -> ret)
55+ , Entered n m (a -> ret) ~ (a -> typ)
56+ , Enter typ m n ret
57+ )
58+ => Enter (a -> typ) m n (a -> ret)
59+ where
4060 enter arg f a = enter arg (f a)
4161
4262-- ** Useful instances
4363
44−instance Enter (m a) (m :~> n) (n a) where
64+instance Enter (m a) m n (n a) where
4565 enter (NT f) = f
4666
4767-- | Like `lift`.