Я надеялся, что кто-то может пролить свет на черную магию в Data.Reflection. Соответствующий фрагмент:
{-# LANGUAGE CPP #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE KindSignatures #-}
module Data.Reflection
(
Reifies(..)
, reify
) where
import Data.Proxy
import Unsafe.Coerce
class Reifies s a | s -> a where
-- | Recover a value inside a 'reify' context, given a proxy for its
-- reified type.
reflect :: proxy s -> a
newtype Magic a r = Magic (forall (s :: *). Reifies s a => Proxy s -> r)
-- | Reify a value at the type level, to be recovered with 'reflect'.
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
- Я не могу разобрать определение для
reify
. возможно, я пропустил что-то простое о порядке оценки, но похоже, чтоunsafeCoerce::a->b
применяется к трем аргументам. - Каковы изоморфные типы, используемые в
unsafeCoerce
? - Где функция
k
фактически оценивается в определенииreify
? -
Где имеются экземпляры для
Reifes
? Например, я могу запустить следующую строку в GHCi только для загрузки Data.Reflection и Data.Proxy(и установки -XScopedTypeVariables):.reify (3::Int) (\(_:: Proxy q) -> print $ reflect (Proxy :: Proxy q))
-
Где/что такое тип phantom reified?
- Что такое "волшебство" в
newtype Magic
?