Bu belki sanest yaklaşım değildir, ama biz bir TypeRep hakkında yalan benim reflection
paketini kötüye kullanabilir.
{-# LANGUAGE Rank2Types, FlexibleContexts, ScopedTypeVariables #-}
import Data.Dynamic
import Data.Proxy
import Data.Reflection
import GHC.Prim (Any)
import Unsafe.Coerce
newtype WithRep s a = WithRep { withRep :: a }
instance Reifies s TypeRep => Typeable (WithRep s a) where
typeOf s = reflect (Proxy :: Proxy s)
şimdi bizim Dynamic
Tartışmanın TypeRep
gözetleme ve uygun bizim Dynamic
fonksiyonunu örneğini göz önüne alındığında. Bizim için apD
, ama bu bir rütbe 2 tip gerektirir ve Typeable
/Dynamic
gibi base
sadece verilen şey bunları önlemek için yönetiyorsanız
apD :: forall f. Typeable1 f => (forall a. a -> f a) -> Dynamic -> Dynamic
apD f a = dynApp df a
where t = dynTypeRep a
df = reify (mkFunTy t (typeOf1 (undefined :: f()) `mkAppTy` t)) $
\(_ :: Proxy s) -> toDyn (WithRep f :: WithRep s (() -> f()))
O Data
olmasa bile, çok daha kolay olabilir.
başka yolu Dynamic
uygulanmasını istismar sadece olacaktır: Kendi Dynamic'
veri türüne
data Dynamic = Dynamic TypeRep Any
ve unsafeCoerce
, sen içlerinde TypeRep
ile yapmanız gerekenler yapın ve fonksiyonu uygulandıktan sonra , unsafeCoerce
her şey geri döndü.
"Polytypeable" ve "polytypeable-utils" için kullanılabilir gibi görünüyor - yine de en iyi durumda, tam birleştirme uygulamak zorunda olsa da. – Carl