Created
June 30, 2016 22:51
-
-
Save yuga/3a13da378383c967caf5cad1c7e87308 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 KindSignatures #-} | |
{-# LANGUAGE MultiParamTypeClasses #-} | |
{-# LANGUAGE Rank2Types #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
module ReflectionTest where | |
import Data.Proxy | |
import Unsafe.Coerce | |
data Config = Config | |
{ test :: Bool | |
, dir :: FilePath | |
} | |
defaultConfig :: Config | |
defaultConfig = Config | |
{ test = False | |
, dir = "/Users/yuga" | |
} | |
class Reifies s a | s -> a where | |
reflect :: proxy s -> a | |
newtype Magic a r = Magic (forall (s :: *). Reifies s a => Proxy s -> r) | |
reify :: forall a r. a -> (forall (s :: *). Reifies s a => Proxy s -> r) -> r | |
reify a k = unsafeCoerce (Magic k :: Magic a r) (const a) Proxy | |
t :: FilePath | |
t = reify defaultConfig compose --(\p -> dir (reflect p) ++ "/test" ) | |
compose :: Reifies s Config => Proxy s -> FilePath | |
compose p = dir (reflect p) ++ "/test" | |
-- Another implementation into which the above turns | |
newtype AnotherReifies s a = AnotherReifies { anotherReflect :: Proxy s -> a } | |
newtype AnotherMagic a r = AnotherMagic (forall s. AnotherReifies s a -> Proxy s -> r) | |
anotherReify :: forall a r. a -> (forall s. AnotherReifies s a -> Proxy s -> r) -> r | |
anotherReify a k = unsafeCoerce (AnotherMagic k :: AnotherMagic a r) (const a) Proxy | |
t2 :: FilePath | |
t2 = anotherReify defaultConfig compose2 | |
compose2 :: AnotherReifies s Config -> Proxy s -> FilePath | |
compose2 dict p = dir (anotherReflect dict p) ++ "/test" | |
-- More another implementation | |
anotherReify2 :: forall a r. a -> (forall s. AnotherReifies s a -> Proxy s -> r) -> r | |
anotherReify2 a k = | |
(unsafeCoerce :: (forall s. AnotherReifies s a -> Proxy s -> r) -> (Proxy s -> a) -> Proxy s -> r) | |
k (const a) Proxy | |
t3 :: FilePath | |
t3 = anotherReify2 defaultConfig compose2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment