Haskell Data.Typeable.cast转换为存在类型

Haskell Data.Typeable.cast转换为存在类型,haskell,types,casting,typeclass,existential-type,Haskell,Types,Casting,Typeclass,Existential Type,这是我的对象系统传奇(,)的延续 这一部分主要包括以下内容 {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE KindSignatures #-} import Data.Typeable import GHC.Exts (Constraint) data Obj (cls :: * -> Constraint) = forall o. (cls o, Typ

这是我的对象系统传奇(,)的延续

这一部分主要包括以下内容

{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE KindSignatures #-}

import Data.Typeable
import GHC.Exts (Constraint)

data Obj (cls :: * -> Constraint) = forall o. (cls o, Typeable o) => Obj o

downcast :: Obj a -> Maybe (Obj b)
downcast (Obj x) = do
                     cx <- cast x
                     return $ Obj cx

我不太明白为什么会发生这个错误:(它能被修复吗?

当你的Haskell被翻译成GHC核心时,类(以及伴随而来的逻辑编程构造,比如隐式)它们被编译器转换成字典传递代码-每个
实例
成为一条记录(常规值),每个方法成为该记录的一个成员。(有关更多详细信息,请参阅。)

所以一个封装了约束的构造函数

data Obj c where——我使用的是GADT语法
Obj::c a=>a->Obj c
在运行时由常规产品类型表示

数据对象,其中
Obj::c a->a->Obj c
其中,
ca
字段是表示
ca
实例的运行时方法字典

要在运行时将
objc
向下转换为
objc'
,即使您有办法测试具体的
a
c
c'
的实例,您仍然必须以某种方式为
c'
合成一个字典。因为
c'
通常包含的方法比
c
多,这相当于要求计算机为您编写一个程序


,我认为最好的办法是在封闭世界的假设下,将关于特定类层次结构的知识构建到运行时系统中。如果您有一个可以查找实例实际运行时的oracle

oracle::MonadRuntime m=>typerepa->typerepc->m(可能(Dict(ca)))
然后,您可以编写
cast
(与一些不舒服的类型争论):

数据对象,其中
Obj::c a=>TypeRep a->a->Obj c
cast::forall c'm.(MonadRuntime m,Typeable c')=>objc->m(可能是(objc'))
铸造(Obj tr x)=do

mdict您尚未在
a
b
之间建立任何关系。因此GHC不知道其中一个隐含着另一个。更具体地说,GHC不知道如何从
ao
字典中获取
bo
字典。我认为您注定要失败,除非您以某种方式手动细化类层次结构。@dfeuer More具体地说,GHC不知道如何从AO字典中获得BO字典是的,这就是我所理解的。我认为你注定要失败,除非你以某种方式手动具体化类层次结构。我并不完全反对。你知道一种构建这种具体化层次结构的方法吗?
约束
包中有一些积垢可能会觉得很鼓舞人心,但我不认为这是你想要做的事情的正确形式。我可以手动提供字典。比如说,每个想要升级的类型都需要是
类Castable
的一个实例,使用一个以某种形式提供字典列表的方法。
downcast
d并返回
只要
正确的字典,或者如果没有匹配,则返回
Nothing
。我正在努力为这个列表提供合适的类型。哇,这是一些高级魔法,我不确定我是否能胜任此任务。。。
• Could not deduce: b o0 arising from a use of ‘Obj’
  from the context: (a o, Typeable o)
    bound by a pattern with constructor:
               Obj :: forall (cls :: * -> Constraint) o.
                      (cls o, Typeable o) =>
                      o -> Obj cls,
             in an equation for ‘downcast’
    at downcast.hs:12:11-15
• In the second argument of ‘($)’, namely ‘Obj cx’
  In a stmt of a 'do' block: return $ Obj cx
  In the expression:
    do cx <- cast x
       return $ Obj cx
• Relevant bindings include
    cx :: o0 (bound at moo.hs:13:22)
    downcast :: Obj a -> Maybe (Obj b) (bound at downcast.hs:12:1)