到目前为止只有编译错误:
groupElems :: Eq a => [a] -> [[a]]
groupElems [] = []
groupElems (x:xs) =
let (a,b) = span (<= x) xs
in a : (groupElems b)
谢谢。
错误:
Could not deduce (Ord a) arising from a use of ‘<=’
from the context (Eq a)
bound by the type signature for groupElems :: Eq a => [a] -> [[a]]
答案 0 :(得分:8)
编译器说:
Could not deduce (Ord a) arising from a use of ‘<=’ from the context (Eq a) bound by the type signature for groupElems :: Eq a => [a] -> [[a]]
Haskell编译器的目的是说您使用<= x
代码,但<=
函数不是 Eq
类型类的一部分:如果我们问<=
来自哪里,我们会得到:
Prelude> :i (<=)
class Eq a => Ord a where
...
(<=) :: a -> a -> Bool
...
-- Defined in ‘GHC.Classes’
infix 4 <=
因此我们可以使用Ord
类型类来解决问题:它意味着元素是有序的。但根据您的示例,这是不您想要的。如果我们使用Ord a
作为类型约束,例如:
groupElems :: Ord a => [a] -> [[a]]
groupElems [] = []
groupElems (x:xs) =
let (a,b) = span (<= x) xs
in a : (groupElems b)
第二个问题是我们*在span
列表上调用xs
。 xs
是列表的 tail 。这意味着我们不会考虑到头脑。我们可以使用别名@
来更改此设置并处理整个列表xa
:
groupElems :: Ord a => [a] -> [[a]]
groupElems [] = []
groupElems xa@(x:_) =
let (a,b) = span (<= x) xa
in a : (groupElems b)
我们将获得:
GHci > groupElems []
[]
GHci > groupElems [1,2]
[[1],[2]]
GHci > groupElems [1,2,2,2,4]
[[1],[2,2,2],[4]]
GHci > groupElems [1,2,3,2,4]
[[1],[2],[3,2],[4]]
请注意,最后一个测试用例不正确。这是因为3
和2
都满足<= 3
谓词。
如果您想按相等进行分组,则应使用(==) :: Eq a => a -> a -> Bool
函数:
groupElems :: Eq a => [a] -> [[a]]
groupElems [] = []
groupElems xa@(x:_) =
let (a,b) = span (== x) xa -- use == instead of <=
in a : (groupElems b)
然后产生:
GHci > groupElems []
[]
GHci > groupElems [1,2]
[[1],[2]]
GHci > groupElems [1,2,2,2,4]
[[1],[2,2,2],[4]]
GHci > groupElems [1,2,3,2,4]
[[1],[2],[3],[2],[4]]
答案 1 :(得分:3)
编译器说a
必须是Ord
类型类的实例,因为使用<=
。所以你可以纠正你的代码:
groupElems :: Ord a => [a] -> [[a]]
但是,如果您仍然需要使用Eq
,则可以使用==
代替<=
,代码就可以使用。
我还注意到,您的代码版本在[1, [], [3]]
示例中返回了[1,2,2,3,3]
,因为您传递了xs
而不是整个列表。
groupElems :: Eq a => [a] -> [[a]]
groupElems [] = []
groupElems all@(x:xs) =
let (a,b) = span (== x) all
in a : (groupElems b)
顺便说一下,Data.List
模块中的group功能完全符合您的目标
答案 2 :(得分:2)
您正在约束您的功能,以便a
必须属于班级Eq
。但是,函数<=
属于Ord
类型类。尝试将函数注释更改为:
groupElems :: Ord a => [a] -> [[a]]
答案 3 :(得分:2)
我认为你要找的是Data.List.group;
Prelude> Data.List.group [1,2,2,2,4]
[[1],[2,2,2],[4]]