是否有理智的方法将多态函数应用于Dynamic
类型的值?
例如,我有一个Dynamic
类型的值,我想将Just
应用于Dynamic
内部的值。因此,如果该值是由toDyn True
构造的,我希望结果为toDyn (Just True)
。 Dynamic
内部可能出现的不同类型的数量没有限制。
(当涉及的类型来自封闭的Universe时,我有一个解决方案,但这很不愉快。)
最佳答案
这也许不是最明智的方法,但是我们可以滥用我的reflection
包来欺骗TypeRep。
{-# 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)
鉴于我们现在可以窥视
TypeRep
参数的Dynamic
并适当地实例化Dynamic
函数。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 ()))
如果
base
刚刚为我们提供了类似apD
的内容,则可能会容易得多,但这需要2级类型,并且Typeable
/ Dynamic
设法避免使用它们,即使Data
不需要。另一条途径是仅利用
Dynamic
的实现:data Dynamic = Dynamic TypeRep Any
和
unsafeCoerce
转换为您自己的Dynamic'
数据类型,对内部的TypeRep
进行所需的操作,然后在应用函数后,将unsafeCoerce
的所有内容返回。关于haskell - 如何将多态函数应用于动态值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10889682/