顶级 OverloadedLists 文字
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), <b>Item (l Foo) ~ Foo</b>) => [Case l]
cases = [
Case { description = "blah blah"
, input = [Foo 1, Foo 2, Foo 3]
, expected = Foo 1
}
]
这里我们说Item (l Foo)
应该和Foo
一样。
我有一个用于重构练习的测试套件,我希望它与 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), <b>Item (l Foo) ~ Foo</b>) => [Case l]
cases = [
Case { description = "blah blah"
, input = [Foo 1, Foo 2, Foo 3]
, expected = Foo 1
}
]
这里我们说Item (l Foo)
应该和Foo
一样。