【发布时间】:2018-03-03 06:11:36
【问题描述】:
当我尝试创建一个返回 Thing a 的函数(其中 Thing 是 GADT)时,我目前正在与类型检查器发生争执。一个最小的人为示例:
{-#LANGUAGE GADTs, EmptyDataDecls #-}
module Main where
-- Define a contrived GADT
data TFoo
data TBar
data Thing a where
Foo :: Int -> Thing TFoo
Bar :: String -> Thing TBar
combine :: [Thing a]
combine = [Foo 1, Bar "abc"]
main :: IO ()
main = undefined
类型检查器对a 不匹配TBar 感到不满。大概这是因为它已经推断出a 是TFoo。但是,这令人惊讶,因为您可以使用常规 sum 类型:
data Thing = Foo Int | Bar String
combine :: [Thing]
combine = [Foo 1, Bar "abc"]
是否有返回 GADT 参数的类型参数?
在人为示例的上下文之外,我需要 GADT,因此我可以键入某些函数以仅获取 Foo,但在此之前我还需要能够仅返回 Things 的列表。
【问题讨论】:
-
我认为您的问题是列表必须是同质的。正如您所指出的,您可以拥有
[Thing],但您不能在同一个列表中使用两个不同的Thing a。 -
@jkeuhlen 对。这对于像
[1, "a"]这样明显不同的类型是有意义的,但我对 GADT 和 sum 类型之间的奇偶性有点困惑。Thing a不是Foo和Bar的“最终返回类型”。是否有任何类型包含Foo 1和Bar "abc"的结果? -
不,
Thing a不是构造函数的最终返回类型。他们明确地创建了一个Thing TFOO和一个Thing TBar。