Мне нужно написать функцию, которая сглаживает список списков.
Например, flatten [] = []
или flatten [1,2,3,4] = [1,2,3,4]
или flatten [[1,2],[3],4,5]] = [1,2,3,4,5]
У меня проблемы с возможностью сопоставить тип в зависимости от того, что задано функции сглаживания.
Вот что у меня есть:
data A a = B a | C [a] deriving (Show, Eq, Ord)
flatten::(Show a, Eq a, Ord a)=>A a -> A a
flatten (C []) = (C [])
flatten (C (x:xs) ) = (C flatten x) ++ (C flatten xs)
flatten (B a) = (C [a])
Из того, что я могу сказать, проблема заключается в том, что оператор ++
ожидает список для обоих своих аргументов, и я пытаюсь дать ему что-то типа A
. Я добавил тип A
, чтобы функция могла получить либо один элемент, либо список элементов.
Кто-нибудь знает другой способ сделать это по-другому или объяснить, что я могу сделать, чтобы исправить ошибку типа?
flatten :: A [a] -> A a; flatten (B xs) = C xs; flatten (C xss) = C (concat xss)
поможет вам? По сути, вы не можете написать flatten так, чтобы он брал списки с разной вложенностью и делал с ними разные вещи, если только вы не завернете их в новый тип и не разграничите случаи по конструктору. - person Daniel Fischer   schedule 01.03.2012[[a]] -> [a]
. Это означает, чтоflatten []
допустимо,flatten [[1,2,3,4]]
допустимо, аflatten [1,2,3,4]
нет.[1,2,3,4]
не является списком списков. Если вы подумаете об этом и начнете с самого начала, избавившись от своего особого типа, вам будет намного легче. - person Dan Hulme   schedule 01.03.2012