到目前为止只有编译错误:
groupElems :: Eq a => [a] -> [[a]]
groupElems [] = []
groupElems (x:xs) =
let (a,b) = span (<= x) xs
in a : (groupElems b)
Run Code Online (Sandbox Code Playgroud)
谢谢.
错误:
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]]
Run Code Online (Sandbox Code Playgroud)
编译器说:
Run Code Online (Sandbox Code Playgroud)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 <=
Run Code Online (Sandbox Code Playgroud)
所以我们可以通过使用Ord类型类来解决这个问题:它意味着元素是有序的.但根据你的例子,这不是你想要的.如果我们使用Ord a类型约束,例如:
groupElems :: Ord a => [a] -> [[a]]
groupElems [] = []
groupElems (x:xs) =
let (a,b) = span (<= x) xs
in a : (groupElems b)Run Code Online (Sandbox Code Playgroud)
第二个问题是,我们*调用span上的xs列表.xs是列表的尾部.这意味着我们不会考虑到头脑.我们可以通过使用别名来改变它@并处理整个列表xa:
groupElems :: Ord a => [a] -> [[a]]
groupElems [] = []
groupElems xa@(x:_) =
let (a,b) = span (<= x) xa
in a : (groupElems b)Run Code Online (Sandbox Code Playgroud)
我们将获得:
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]]
Run Code Online (Sandbox Code Playgroud)
请注意,最后一个测试用例不正确.这是因为两者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)Run Code Online (Sandbox Code Playgroud)
然后产生:
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]]
Run Code Online (Sandbox Code Playgroud)