繁体   English   中英

使用类型系列,GADT和命名记录编译错误

[英]Compile error with type families, GADTs and named records

在下面的代码中, T1T2编译正常,但T3失败:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}

type family F a

data T1 b where
  T1 :: a -> T1 (F a)

data T2 b where
  T2 :: { x2 :: a } -> T2 a

data T3 b where
  T3 :: { x3 :: a } -> T3 (F a)

我想知道为什么。 T3只是T1但有一个命名记录。 这看起来并不那么特别,因为无论如何都可以使用构造函数语法来提取它。

这些例子可能都看傻了,但在我的代码中有一个约束的a ,例如(Show a) ,所以要提取时,他们可以使用这些值。

让我们忘记T2T3 ,然后尝试为T1定义一个提取器函数。 该类型应该是什么?

x1 :: ???
x1 (T1 a) = a

好吧,你可能会猜到x1 :: T1 (F a) -> a 但那是不对的,如果你尝试一下,那么你将得到与定义T3相同的错误。

问题是,如果有人给你一个T1 T ,并且你碰巧知道类型A使得FAT ,你就不能断定T1 T包含类型A的值,因为它可能包含另一个带有FB类型B等于T 作为极端情况,假设我们有

type instance F _ = ()

那么如果我们猜测x1 :: T1 (F a) -> a ,我们就有了

T1 :: a -> T1 ()
x1 :: T1 () -> b

编写这些会让我们写a -> b ,这很糟糕。

x1的真实类型类似于存在主义提供约束

T1 t -> (exists a. (F a ~ t) *> a)

哪个GHC不支持。

T3的问题实际上与您的问题相同

data T3' where T3' :: { x3' :: a } -> T3'

您可以使用模式匹配提取字段(如果有更多字段或约束,这可能很有用),但不能使用记录选择器或函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM