[英]Top-level OverloadedLists literal
I've got a test suite for a refactoring exercise where I'd like it to be compatible with both Data.List
and Data.List.NonEmpty
.我有一个用于重构练习的测试套件,我希望它与Data.List
和Data.List.NonEmpty
兼容。 The exercise consists of a function foo :: [Foo] -> Foo
and the test suite has some练习包含一个函数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
}
, ...
]
To make the test suite polymorphic with OverloadedLists
, I tried为了使用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
}
, ...
]
but this gives me the error但这给了我错误
• 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]
| ^^^^^
I thought to move the IsList list
constraint to the Case
data type, like so我想将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), ... ]
but this gives me the error但这给了我错误
• 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
| ^^^^^^^^
I'm not sure what the simplest approach here is.我不确定这里最简单的方法是什么。 Any hints?任何提示?
The reason this does not work is because the Item
type of a List (l Foo) => l
is not per se Foo
.这不起作用的原因是因为List (l Foo) => l
的Item
类型本身不是Foo
。 The extension makes abstraction of that, and thus it expects the elements of your list literal to be of type Item (l Foo)
.该扩展对其进行了抽象,因此它期望您的列表文字的元素为Item (l Foo)
类型。
You can however add a type constraint that says that the items are indeed of type 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
}
]
Here we thus say that the Item (l Foo)
should be the same as Foo
.因此,我们在这里说Item (l Foo)
应该与Foo
相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.