2017-01-03 5 views
1

Я изучаю haskell и пытаюсь реализовать функцию tails. Это моя реализация:Реализация функции хвостов в haskell

tails' :: [a] -> [[a]] 
tails' [] = [] 
tails' (x:xs) = xs:[[tails' xs]] 

Но я продолжаю нарваться ошибки компиляции

Couldn't match expected type ‘a’ with actual type ‘[[a]]’ 
     ‘a’ is a rigid type variable bound by 
      the type signature for tails' :: [a] -> [[a]] at.. 

Что не так с моей реализации?

+2

Подпись вашего типа '' tails 'xs' должна быть уже списком списков. Закрывая его в скобках как '[[tails 'xs]]' обертывает этот список списков в двух дополнительных списках Singleton. Все, что вам нужно, это 'tails '(x: xs) = xs: tails' xs'. – Alec

+0

@Alec: Вы правы. Оно работает. Но я до сих пор не понимаю, почему скобки должны быть удалены (кроме того, что он заставляет программу работать :)). Разве это не задача программиста обеспечить, чтобы возвращаемое значение соответствовало таковому в сигнатуре типа? Поскольку способ, которым вы помещаете: подпись типа, заботится о преобразовании его в список списков. – Ashwin

ответ

4

Заменить

tails' (x:xs) = xs:[[tails' xs]] 

с:

tails' (x:xs) = xs : tails' xs 
+2

Вам даже не нужны парады: 'xs: tails 'xs' отлично работает. – melpomene

+0

@Leandro Galvan: Не могли бы вы объяснить, почему вы сняли скобки? – Ashwin

+0

@Ashwin термин 'tails 'xs' без скобок уже является списком списков, т. Е. Типа' [[a]] '. Это немного запутанно, потому что функция рекурсивна, но если вы посмотрите на тип, который вы объявили, он читает, что __tails «принимает список и возвращает список списков __; поскольку 'xs' - это список, применяя его к' tails'', выводится список списков. –

3

Помимо ошибки типа синтаксиса, ваша реализация не является правильным (в спецификации). Сравните это с этим ...

Prelude> let tails [] = [[]] 
Prelude|  tails [email protected](x:xs) = y:(tails xs) 
Prelude| 
Prelude> tails "abc" 
["abc","bc","c",""] 
+2

Это ошибка типа, а не синтаксическая ошибка. – chepner

+0

Даже ваша реализация не относится к спецификации. Сравните результат 'null (tails undefined)' между вашей реализацией и 'Data.List'. –

+0

@ DanielWagner Я вижу, как реализация в Data.List позволяет возвратить 'False' для этого ввода, но почему это полезное свойство, которое' tails undefined = undefined: tails (tail undefined) '? – amalloy

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