Last active
April 10, 2018 11:40
-
-
Save Garciat/b2c37cddf2341ef21242c3496ce63b7f to your computer and use it in GitHub Desktop.
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
{-# LANGUAGE ConstraintKinds #-} | |
{-# LANGUAGE DataKinds #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE GADTs #-} | |
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE PolyKinds #-} | |
{-# LANGUAGE RankNTypes #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
{-# LANGUAGE TypeApplications #-} | |
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE TypeOperators #-} | |
{-# LANGUAGE UndecidableSuperClasses #-} | |
import Data.Aeson | |
import Data.Monoid | |
import Data.Proxy | |
import Data.Text | |
import GHC.Exts (Constraint) | |
--- | |
data Dict :: Constraint -> * where | |
Dict :: a => Dict a | |
data DictList :: (k -> Constraint) -> [k] -> * where | |
Nil :: DictList c '[] | |
Cons :: Dict (c x) -> DictList c xs -> DictList c (x ': xs) | |
-- Let GHC do the heavy lifting! | |
class BuildDictList c ts where | |
buildDictList :: DictList c ts | |
instance BuildDictList c '[] where | |
buildDictList = Nil | |
instance (c t, BuildDictList c ts) => BuildDictList c (t ': ts) where | |
buildDictList = Cons Dict buildDictList | |
--- | |
class MapDictList c ts where | |
mapDictList :: (forall a. Dict (c a) -> b) -> DictList c ts -> [b] | |
instance MapDictList c '[] where | |
mapDictList _ Nil = [] | |
instance MapDictList c ts => MapDictList c (t ': ts) where | |
mapDictList f (Cons x xs) = f x : mapDictList f xs | |
--- | |
mapTypes :: forall (c :: k -> Constraint) (ts :: [k]) (b :: *). | |
(BuildDictList c ts, MapDictList c ts) | |
=> Proxy c | |
-> Proxy ts | |
-> (forall a. c a => Proxy a -> b) -> [b] | |
mapTypes Proxy Proxy f = | |
mapDictList | |
(\(Dict :: Dict (c a)) -> f (Proxy :: Proxy a)) | |
(buildDictList :: DictList c ts) | |
--- | |
class Trivial a | |
instance Trivial a | |
class (f a, g a) => (f & g) a | |
instance (f a, g a) => (f & g) a | |
--- | |
-- Just for the PoC: | |
class ToYAML a | |
instance ToJSON a => ToYAML a | |
renderJSONSchema :: (ToJSON a) => Proxy a -> Text | |
renderJSONSchema = undefined | |
renderYAMLSchema :: (ToYAML a) => Proxy a -> Text | |
renderYAMLSchema = undefined | |
--- | |
--- Usage | |
type SerializedTypes = [Int, Bool, String] | |
createCombinedJSONSchema = | |
mconcat $ | |
mapTypes | |
(Proxy @ToJSON) | |
(Proxy @SerializedTypes) | |
renderJSONSchema | |
createCombinedYAMLSchema = | |
mconcat $ | |
mapTypes | |
(Proxy @(ToJSON & ToYAML & Show)) -- just e.g. | |
(Proxy @SerializedTypes) | |
renderYAMLSchema |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment