[英]Top-level OverloadedLists literal
我有一個用於重構練習的測試套件,我希望它與Data.List
和Data.List.NonEmpty
兼容。 練習包含一個函數foo :: [Foo] -> Foo
並且測試套件有一些
data Case = Case
{ description :: String
, input :: [Foo]
, expected :: Foo
}
cases :: [Case]
cases =
[ Case { description = "blah blah"
, input = [Foo 1, Foo 2, Foo 3]
, expected = Foo 1
}
, ...
]
為了使用OverloadedLists
使測試套件具有多態性,我嘗試了
{-# LANGUAGE OverloadedLists #-}
...
data Case list = Case
{ description :: String
, input :: list Foo
, expected :: Foo
}
cases =
[ Case { description = "blah blah"
, input = [Foo 1, Foo 2, Foo 3]
, expected = Foo 1
}
, ...
]
但這給了我錯誤
• Couldn't match expected type ‘GHC.Exts.Item (list0 Foo)’
with actual type ‘Foo’
The type variable ‘list0’ is ambiguous
...
|
50 | , input = [Foo 1, Foo 2, Foo 3]
| ^^^^^
我想將IsList list
約束移動到Case
數據類型,就像這樣
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedLists #-}
...
data Case list where
Case :: IsList list => String -> list Foo -> Foo -> Case list
cases =
[ Case "blah blah" [Foo 1, Foo 2, Foo 3] (Foo 1), ... ]
但這給了我錯誤
• Expected kind ‘* -> *’, but ‘list’ has kind ‘*’
• In the type ‘list Foo’
In the definition of data constructor ‘Case’
In the data declaration for ‘Case’
|
24 | Case :: IsList list => String -> list Foo -> Foo -> Case list
| ^^^^^^^^
我不確定這里最簡單的方法是什么。 任何提示?
這不起作用的原因是因為List (l Foo) => l
的Item
類型本身不是Foo
。 該擴展對其進行了抽象,因此它期望您的列表文字的元素為Item (l Foo)
類型。
但是,您可以添加一個類型約束,表明這些項目確實是Foo
類型:
{-# LANGUAGE OverloadedLists #-}
data Case list = Case
{ description :: String
, input :: list Foo
, expected :: Foo
}
cases :: (IsList (l Foo), Item (l Foo) ~ Foo) => [Case l]
cases = [
Case { description = "blah blah"
, input = [Foo 1, Foo 2, Foo 3]
, expected = Foo 1
}
]
因此,我們在這里說Item (l Foo)
應該與Foo
相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.