繁体   English   中英

GADT与自定义数据类型的混淆?

[英]GADT confusion with custom data types?

我有以下自定义数据类型:

data FirstPair' a b = FirstPair a b deriving (Show, Ord, Eq)
type FirstPair a = FirstPair' a a 

data SecondPair' a b = SecondPair a b deriving (Show, Ord, Eq)
type SecondPair a = SecondPair' a a 

我正在尝试为我的函数创建一个GADT结构:

data Generator a where
  Success :: FirstPair a -> Generator (SecondPair a)
  Fail :: FirstPair a -> Generator Bool

myFunction :: Generator a -> a
myFunction (Success fp) = SecondPair "21" "24"
myFunction (Fail fp) = False

'Generator'类型的作用是让我强制'myFunction'返回'SecondPair'的实例,如果'Success'被传递给它,并且'False'如果'Fail'传递给它。

但是,我收到此错误:

"Could not deduce: a1 ~ [Char] from the context: a ~ SecondPair' a1 a1 bound by a pattern with constructor: Success :: forall a. FirstPair a -> Generator (SecondPair a)"

我在这做错了什么?

myFunction :: Generator a -> a
myFunction (Success fp) = SecondPair "21" "24"
myFunction (Fail fp) = False

问题出在这里。 类型签名是简写

myFunction :: forall a. Generator a -> a

也就是说,不管是什么类型a我去接,如果我给myFunction一个Generator a ,它会给我回来的a 所以,如果我给它一个Generator Int ,它应该给我一个Int

所以我可以构建

successval :: Generator (SecondPair Int)
successval = Success (FirstPair 42 42 :: FirstPair Int)

然后将它传递给myFunction ,并根据我应该得到的类型签名

myFunction successVal :: SecondPair Int

但是,定义myFunction的方式,无论我传递的是什么类型,它总会返回一个SecondPair String ,这就是它所抱怨的问题。

如果你想要这种多态性,你需要以某种方式使用你给出的参数。 例如

myFunction (Success (FirstPair x y)) = SecondPair x y

会做的伎俩,因为xy走出去都是同一类型的xy在未来(和FirstPairSecondPair的方式匹配GADT说,他们应该)。

如果你需要返回一个SecondPair String ,那么myFunction的类型签名是错误的,需要像

 myFunction :: Generator a -> SecondPair String

(在Fail的情况下,这种行为不正确 - 我还有更多的话要说这是你真正想去的路线,但是它比我想写的黑暗中更多的参与猜测)

或者GADT需要说结果将是SecondPair String

 data Generator a where
     Success :: FirstPair a -> Generator (SecondPair String)
     ...

我不认为这些是非常可能的场景,我只是认为它们可能有助于您理解问题。

暂无
暂无

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

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