Last active
April 5, 2018 10:07
-
-
Save sopvop/1b6bdbf35dc1d5105a061ef295836e15 to your computer and use it in GitHub Desktop.
Works in servant-server, can't make my own instances
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{- | |
src/Servant/API/RPC.hs:74:8-55: error: … | |
Conflicting family instance declarations: | |
ServerT (RPC e r) m = m (Either (OpenUnion e) r) | |
-- Defined at /home/lonokhov/work/stagex-store/stagex-api/src/Servant/API/RPC.hs:74:8 | |
ServerT (RPC e (Headers h r)) m = m (Headers | |
h (Either (OpenUnion e) r)) | |
-- Defined at /home/lonokhov/work/stagex-store/stagex-api/src/Servant/API/RPC.hs:81:8 | |
-} | |
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE OverloadedLists #-} | |
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE PolyKinds #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
{-# LANGUAGE TupleSections #-} | |
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE TypeOperators #-} | |
data RPC e r | |
instance {-# OVERLAPPABLE #-} (ToJSON (ErrUnion e), ToJSON r) | |
=> HasServer (RPC e r) ctx where | |
type ServerT (RPC e r) m = m (Either (OpenUnion e) r) | |
hoistServerWithContext _ _ nt = nt | |
route Proxy _ = methodRouter' $ \x -> (getHeaders x, getResponse x) | |
instance {-# OVERLAPPING #-} (ToJSON (ErrUnion e), ToJSON r, GetHeaders (Headers h r)) | |
=> HasServer (RPC e (Headers h r)) ctx where | |
type ServerT (RPC e (Headers h r)) m = m (Headers h (Either (OpenUnion e) r)) | |
hoistServerWithContext _ _ nt = nt | |
route Proxy _ = methodRouter' ([],) | |
{- As defined in servant, and it works. using same -Xtensions #-} | |
instance OVERLAPPABLE_ | |
( AllCTRender ctypes a, ReflectMethod method, KnownNat status | |
) => HasServer (Verb method status ctypes a) context where | |
type ServerT (Verb method status ctypes a) m = m a | |
hoistServerWithContext _ _ nt s = nt s | |
route Proxy _ = methodRouter ([],) method (Proxy :: Proxy ctypes) status | |
where method = reflectMethod (Proxy :: Proxy method) | |
status = toEnum . fromInteger $ natVal (Proxy :: Proxy status) | |
instance OVERLAPPING_ | |
( AllCTRender ctypes a, ReflectMethod method, KnownNat status | |
, GetHeaders (Headers h a) | |
) => HasServer (Verb method status ctypes (Headers h a)) context where | |
type ServerT (Verb method status ctypes (Headers h a)) m = m (Headers h a) | |
hoistServerWithContext _ _ nt s = nt s | |
route Proxy _ = methodRouter (\x -> (getHeaders x, getResponse x)) method (Proxy :: Proxy ctypes) status | |
where method = reflectMethod (Proxy :: Proxy method) | |
status = toEnum . fromInteger $ natVal (Proxy :: Proxy status) | |
{- fixed by moving Either to head -} | |
instance {-# OVERLAPPABLE #-} (ToJSON (ErrUnion e), ToJSON r) | |
=> HasServer (RPC e (Either (OpenUnion e) r)) ctx where | |
type ServerT (RPC e (Either (OpenUnion e) r)) m = m (Either (OpenUnion e) r) | |
hoistServerWithContext _ _ nt = nt | |
route Proxy _ = methodRouter' ([],) | |
instance {-# OVERLAPPING #-} | |
( ToJSON (ErrUnion e) | |
, ToJSON r | |
, GetHeaders (Headers h (Either (OpenUnion e) r))) | |
=> HasServer (RPC e (Headers h (Either (OpenUnion e) r))) ctx where | |
type ServerT (RPC e (Headers h (Either (OpenUnion e) r))) m = m (Headers h (Either (OpenUnion e) r)) | |
hoistServerWithContext _ _ nt = nt | |
route Proxy _ = methodRouter' $ \x -> (getHeaders x, getResponse x) | |
{- Solution 2 -} | |
class GetRpcResult r e a | r -> e, r -> a where | |
getRpcResult :: r -> RpcResult e a | |
instance GetRpcResult (Either (OpenUnion e) a) e a where | |
getRpcResult = \case | |
Right r -> RpcSuccess r | |
Left e -> RpcError e | |
instance {-# OVERLAPPABLE #-} | |
( ToJSON (ErrUnion e) | |
, ToJSON a | |
, GetRpcResult r e a) | |
=> HasServer (RPC e r) ctx where | |
type ServerT (RPC e r) m = m r | |
hoistServerWithContext _ _ nt = nt | |
route Proxy _ = methodRouter' | |
$ \x -> ([], getRpcResult x :: RpcResult e a) | |
instance {-# OVERLAPPING #-} | |
( ToJSON (ErrUnion e) | |
, ToJSON a | |
, GetRpcResult r e a | |
, GetHeaders (Headers h r)) | |
=> HasServer (RPC e (Headers h r)) ctx where | |
type ServerT (RPC e (Headers h r)) m = m (Headers h r) | |
hoistServerWithContext _ _ nt = nt | |
route Proxy _ = methodRouter' | |
$ \x -> (getHeaders x, getRpcResult (getResponse x) :: RpcResult e a) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment