Reflection库中有一个现有的类
class Reifies s a | s -> a where ...
(所以我不能改变这个课程)。 我觉得应该可以将函数依赖表达为包装类中的类型族同义词,这样我就可以做类似的事情了
class (Reifies s a) => ReifiesWrapper s a where
type ReifiedType s
然后在ReifiesWrapper set
的实例中type ReifiedType s = a
当然我不能这样做,因为没有出现在LHS上。这似乎应该是可能的,因为(由于Reify中的FunDep),知道s足以找到类型a。
总体目标是隐藏“具体类型”a:
class Reified q where
...
instance (Reified q) => Blah q
type ReifiedBlah q = ReifiedType q
我希望在这里过多吗?
谢谢, 埃里克
答案 0 :(得分: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
之间的关联可以表示为equality constraint。
UPDATE :适用于1-parametric包装器,类型系列超过2参数类,带有fundep:
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