Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
{-# 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
You can’t perform that action at this time.