4

Reflection ライブラリの既存のクラスがあります

class Reifies s a | s -> a where ...

(したがって、このクラスを変更することはできません)。関数の依存関係をラッパー クラスの型ファミリ シノニムとして表現して、次のようなことができるようにすべきだと思います。

class (Reifies s a) => ReifiesWrapper s a where
   type ReifiedType s

次に、ReifiesWrapper セットのインスタンスで

type ReifiedType s = a 

もちろん、LHS には a が表示されないため、これはできません。これはすべて可能であるように思われます。これは、(Reifies の FunDep のおかげで) 型 a を見つけるには s を知っていれば十分であるためです。

全体的な目標は、「具体化された型」を非表示にすることです。

class Reified q where
  ...

instance (Reified q) => Blah q
   type ReifiedBlah q = ReifiedType q

ここに期待しすぎですか?

ありがとう、エリック

4

1 に答える 1

2

メソッドをラッパーにコピーする場合はReifies、次のように記述できます。

class R s a | s -> a where
  r :: s -> a
  -- etc.

class R s a => RW s a where
  type RT s
  r' :: a ~ RT s => s -> RT s
  r' = r
  -- etc.

instance R Bool String where
  r = show
  -- etc.

instance RW Bool String where
  type RT Bool = String
  -- no need to write r' = r, etc.

-- > :t r
-- r :: R s a => s -> a
-- > :t r'
-- r' :: RW s (RT s) => s -> RT s
-- > :t r True
-- r True :: [Char]
-- > :t r' True
-- r' True :: RT Bool
-- > r True
-- "True"
-- > r' True
-- "True"

aとの間の関連付けを等式制約RT sとして表現できるようにします。


UPDATE : fundep を使用した 2 パラメーター クラスを介したタイプ ファミリーを使用した 1 パラメーター ラッパーの場合:

class R s a | s -> a where
  r :: s -> a

class R' s where
  type RT s a
  r' :: (R s a, a ~ RT s a) => s -> RT s a
  r' = r

instance R Bool String where
  r = show

instance R' Bool where
  type RT Bool a = a

となることによって:

> :t r
r :: R s a => s -> a
> :t r'
r' :: (R' s, R s a, RT s a ~ a) => s -> RT s a
> :t r True
r True :: [Char]
> :t r' True
r' True :: RT Bool [Char]
> r True
"True"
> r' True
"True"

例えば:

import qualified Data.Reflection as Reflection ( reflect )
import Data.Reflection hiding ( reflect )

class Reified s where
  type ReifiedType s a
  reflect :: (Reifies s a, a ~ ReifiedType s a) => proxy s -> ReifiedType s a
  reflect = Reflection.reflect
于 2012-06-22T02:34:45.447 に答える