Dynamic
の値に多相関数を適用するには正当な方法はありますか?多項式関数を動的値に適用する方法
たとえば、タイプがDynamic
で、の値にJust
を適用したいとします。だから値がtoDyn True
によって構築された場合、結果はtoDyn (Just True)
になります。 Dynamic
の内部で発生する可能性があるさまざまな種類の数は制限されていません。
(関与型が閉じられた宇宙から来たとき、私は解決策を持っていますが、それは不快だ。)
Dynamic
の値に多相関数を適用するには正当な方法はありますか?多項式関数を動的値に適用する方法
たとえば、タイプがDynamic
で、の値にJust
を適用したいとします。だから値がtoDyn True
によって構築された場合、結果はtoDyn (Just True)
になります。 Dynamic
の内部で発生する可能性があるさまざまな種類の数は制限されていません。
(関与型が閉じられた宇宙から来たとき、私は解決策を持っていますが、それは不快だ。)
これはおそらく、sanestアプローチではないですが、私たちはTYPEREP偽るために私のreflection
パッケージを乱用することができます。
{-# 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)
私たちは今、私たちDynamic
引数のTypeRep
で覗いて適切たちの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
ていない場合でも、それらを避けるために管理します。あなたが内部でTypeRep
で行う必要がある何を、あなた自身のDynamic'
データ型に
data Dynamic = Dynamic TypeRep Any
とunsafeCoerce
、そしてあなたの関数を適用した後:
別のパスがちょうどDynamic
の実装を利用することであろう、unsafeCoerce
すべてを返します。
これは、 'polytypeable'と' polytypeable-utils'のように見えますが、最悪の場合でも完全な統一を実装する必要があります。 – Carl