是否有理智的方法将多态函数应用于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/

10-13 03:38