module Text.LambdaOptions.Internal.OpaqueParser (
OpaqueParser,
GetOpaqueParsers(..),
) where
import Data.Proxy
import Data.Typeable hiding (typeRep)
import Text.LambdaOptions.Internal.Opaque
import Text.LambdaOptions.Parseable
decomposeFuncProxy :: Proxy (a -> b) -> (Proxy a, Proxy b)
decomposeFuncProxy _ = (Proxy, Proxy)
type OpaqueParser = [String] -> (Maybe Opaque, Int)
parseOpaque :: (Parseable a, Typeable a) => Proxy a -> OpaqueParser
parseOpaque proxy str = case parse str of
(Nothing, n) -> (Nothing, n)
(Just x, n) -> (Just $ Opaque $ x `asProxyTypeOf` proxy, n)
class GetOpaqueParsers r f | f -> r where
getOpaqueParsers :: Proxy f -> [(TypeRep, OpaqueParser)]
instance (Parseable a, Typeable a, GetOpaqueParsers r b) => GetOpaqueParsers r (a -> b) where
getOpaqueParsers funcProxy = let
(proxyA, proxyB) = decomposeFuncProxy funcProxy
typeRep = typeOf proxyA
parser = parseOpaque proxyA
in (typeRep, parser) : getOpaqueParsers proxyB
instance (Monad m) => GetOpaqueParsers r (m r) where
getOpaqueParsers ~Proxy = []