[英]Compile error with type families, GADTs and named records
在下面的代码中, T1
和T2
编译正常,但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)
,所以要提取时,他们可以使用这些值。
让我们忘记T2
和T3
,然后尝试为T1
定义一个提取器函数。 该类型应该是什么?
x1 :: ???
x1 (T1 a) = a
好吧,你可能会猜到x1 :: T1 (F a) -> a
。 但那是不对的,如果你尝试一下,那么你将得到与定义T3
相同的错误。
问题是,如果有人给你一个T1 T
,并且你碰巧知道类型A
使得FA
为T
,你就不能断定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.