连续组合相似的元素

Ole*_*leg 0 haskell

我是Haskell的新手,这就是我想做的事情: 在此输入图像描述

到目前为止只有编译错误:

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)

Wil*_*sem 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]]
Run Code Online (Sandbox Code Playgroud)

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)

请注意,最后一个测试用例不正确.这是因为两者32满足<= 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)