2016-04-07 4 views
0

У меня есть следующий кодHaskell добавить в список в список


groupEq :: Eq a => [a] -> [[a]] 
groupEq list = foldl (\acc x -> if (isType acc x) then ((last acc) ++ [x]) else acc++[[x]]) [] list 

isType :: Eq a => [[a]] -> a -> Bool 
isType list item 
    | (length list) == 0 = False 
    | head (last list) == item = True 
    | otherwise = False 

Теперь я имею трудности понимания того, почему он не будет компилировать. Проблема с частью ((last acc) ++ [x]). Я понимаю это, поскольку он берет последний элемент аккумулятора, который был бы [[a]] на этом этапе и пытается добавить к нему элемент.

Идея, что я хочу, чтобы достичь это: -- groupEq [1,2,2,3,3,3,4,1,1] ==> [[1], [2,2], [3,3,3], [4], [1,1]]

Полная ошибка


Couldn't match type ‘a’ with ‘[a]’ 
     ‘a’ is a rigid type variable bound by 
      the type signature for groupEq :: Eq a => [a] -> [[a]] 
      at exam_revisited.hs:3:12 
    Expected type: [[[a]]] 
     Actual type: [[a]] 
    Relevant bindings include 
     x :: a (bound at exam_revisited.hs:4:28) 
     acc :: [[a]] (bound at exam_revisited.hs:4:24) 
     list :: [a] (bound at exam_revisited.hs:4:9) 
     groupEq :: [a] -> [[a]] (bound at exam_revisited.hs:4:1) 
    In the first argument of ‘last’, namely ‘acc’ 
    In the first argument of ‘(++)’, namely ‘(last acc)’ 

Что я здесь отсутствует?

+0

Занести полную ошибку. – chi

+0

@chi Добавлена ​​ошибка на вопрос – taivo

ответ

1

groupEq объявляется в обратном направлении [[a]], но ((last acc) ++ [x]) имеет тип [a]. Быстрое и грязное решение состоит в том, чтобы изменить это выражение на init acC++ [last acC++ [x]].

+0

@bipill Да, вы действительно правы. Но мне интересно, почему установка аккумулятора на [[]] при запуске не помогла бы. Тогда не будет '((последний acc) ++ [x])' type '[[a]]'? – taivo

+0

Определенно нет. 'last [[]]' is '[]' и имеет тип '[a]'. – bipll

Смежные вопросы