Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 将一个没有约束的GADT转换为另一个有约束的GADT(当此类约束保持时)_Haskell_Dsl_Gadt - Fatal编程技术网

Haskell 将一个没有约束的GADT转换为另一个有约束的GADT(当此类约束保持时)

Haskell 将一个没有约束的GADT转换为另一个有约束的GADT(当此类约束保持时),haskell,dsl,gadt,Haskell,Dsl,Gadt,我们是否可以将一个对其构造函数没有给定约束的GADT转换为一个具有上述约束的GADT?我之所以想这样做,是因为我想深入嵌入箭头,并使用(目前)似乎需要Typeable的表示做一些有趣的事情。() 我们可以从函数中尝试以下,但由于我们没有 Typeable递归点的信息 from :: (Typeable a, Typeable b) => DSL a b -> DSL2 a b from (Id) = Id2 from (Comp g f) = Comp2 (from g

我们是否可以将一个对其构造函数没有给定约束的GADT转换为一个具有上述约束的GADT?我之所以想这样做,是因为我想深入嵌入箭头,并使用(目前)似乎需要
Typeable
的表示做一些有趣的事情。()

我们可以从函数中尝试以下
,但由于我们没有
Typeable
递归点的信息

from :: (Typeable a, Typeable b) =>  DSL a b -> DSL2 a b
from (Id)       = Id2
from (Comp g f) = Comp2 (from g) (from f)
因此,我们尝试在类型类中捕获转换。然而,这将被打破,我们将丢失
Typeable b
信息,因为
b
是存在的

class From a b where
  from :: a -> b

instance (Typeable a, Typeable b) => From (DSL a b) (DSL2 a b) where
  from (Id)       = Id2
  from (Comp g f) = Comp2 (from g) (from f)

还有其他建议吗?最后,我想创建一个深入的
类别
箭头
嵌入,以及
可键入的
类型参数信息。这样我就可以使用箭头语法在DSL中构造一个值,并拥有相当标准的Haskell代码。也许我必须求助于模板Haskell?

递归案例的问题对于将
DSL a b
转换为
DSL2 a b
是致命的

要进行此转换,需要在
Comp
案例中找到存在类型
b
Typeable
字典-但是
b
实际上是什么已经被忘记了

例如,考虑下面的程序:

data X = X Int
-- No Typeable instance for X

dsl1 :: DSL X Char
dsl1 = -- DSL needs to have some way to make non-identity terms,
       -- use whatever mechanism it offers for this.

dsl2 :: DSL Int X
dsl2 = -- DSL needs to have some way to make non-identity terms,
       -- use whatever mechanism it offers for this.

v :: DSL Int Char
v = Comp dsl1 dsl2

v2 :: DSL2 Int Char
v2 = -- made by converting v from DSL to DSL2, note that Int and Char are Typeable

typeOfIntermediate :: DSL a c -> TypeRep
typeOfIntermediate int =
    case int of
        Comp (bc :: DSL2 b c) (ab :: DSL2 a b) ->
            typeOf (undefined :: b)

typeOfX = typeOfIntermediate v2
换句话说,如果有一种方法可以进行一般的转换,那么您可以通过某种方式为一个实际上没有类型的类型创建一个
Typeable
实例

最后,我想创建一个深入的
类别
箭头
嵌入,以及
可键入的
类型参数信息。这样我就可以使用箭头语法在DSL中构造一个值,并拥有相当标准的Haskell代码

也许您应该求助于(注意它意味着
NoImplicitPrelude
)。创建您自己的
arr
(>>)
第一次
应用程序
(| | | |)和
循环
函数,GHC在删除箭头符号时将使用它们,而不是Control.arrow中的标准版本

手册规定“这些功能的类型必须与前奏曲类型非常匹配”。如果您正在构建一个并行类层次结构(Control.Arrow中层次结构的副本,但在类型签名中添加了
Typeable
约束),您应该可以


(注意,我不熟悉箭头符号,因此从未将其与Rebindable语法结合使用;我的答案是一个聪明的猜测。)

在ghc 7.8中,每种类型都会有一个可键入实例,由编译器自动派生,这样障碍就不再适用。事实上,我认为该功能在当前的7.7版本中,因此该限制不再适用于那些愿意勇敢地从源代码构建ghc的人,但即使在ghc 7.8版本中,也没有任何关于存在类型的信息。对于ghc 7.8版本中的新功能,重要的是,尽管每种具体类型都是可键入的,您将无法为/polymorphic/variable假设Typeable,因此,例如,(a->a)类型的唯一total函数仍然必须是identity函数。否则我们会失去参数。不过,它确实使我的特定反参数无效。啊,不知何故,我突然想到,
RebindableSyntax
对箭头不起作用。我将尝试以这种方式解决这个问题。谢谢,我有。但似乎我们最终还是得到了原始的箭头函数。。。
data X = X Int
-- No Typeable instance for X

dsl1 :: DSL X Char
dsl1 = -- DSL needs to have some way to make non-identity terms,
       -- use whatever mechanism it offers for this.

dsl2 :: DSL Int X
dsl2 = -- DSL needs to have some way to make non-identity terms,
       -- use whatever mechanism it offers for this.

v :: DSL Int Char
v = Comp dsl1 dsl2

v2 :: DSL2 Int Char
v2 = -- made by converting v from DSL to DSL2, note that Int and Char are Typeable

typeOfIntermediate :: DSL a c -> TypeRep
typeOfIntermediate int =
    case int of
        Comp (bc :: DSL2 b c) (ab :: DSL2 a b) ->
            typeOf (undefined :: b)

typeOfX = typeOfIntermediate v2