[英]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
會做的伎倆,因為x
和y
走出去都是同一類型的x
和y
在未來(和FirstPair
和SecondPair
的方式匹配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.