Евгений Ш. предложил лучший (простейший) ответ выше: просто использовать map length
на вашем входе.
Но похоже, что эта проблема - домашнее задание, где цель состоит в том, чтобы продемонстрировать основное понимание рекурсии. Так что действительно мы не должны вам помогать :) Но я попытаюсь объяснить так, что это даст больше, чем просто ответ.
С любым рекурсивным определением вы должны сначала определить свои базовые случаи. Поскольку вы имеете дело с списками списков, ваш самый простой случай - это список, содержащий нет подписок - его шаблоны выглядят как []
.
Вы также должны определить рекурсивного случай (иногда также называют индуктивным случаем), в котором правая части уравнения будет содержать ссылку на самую определяемую функцию.
Таким образом, ваши две необходимые определения для функции длины подсписки называется len
:
len (xs:xss) = length xs : len xss
len _ = []
Наша первая линия определяет рекурсивный случай; заметим, что его правая часть содержит ссылку на функцию, которую мы определяем (len
, в этом примере). Мы используем популярные соглашения Haskell от xs
для списка произвольного типа контента и xss
для списка списков.Общий шаблон, (xs:xss)
соответствует любым входным данным со списком (xs
), за которым следует любое количество дополнительных списков (xss
) - примечание, это может означать нулевые другие списки! В этом случае шаблон будет составлять xs:[]
.
Для второй линии мы не удосужились дать явный шаблон - мы использовали шаблон подстановочного номера _
. Это сообщает Haskell (и другим программистам), что мы хотим вернуть []
на номер любой другой номер, отличный от того, который соответствует строке выше. Таким образом, когда наша рекурсия, наконец, доходит до конца списка, она сталкивается с шаблоном, подобным []
- единому списку, за которым не следуют какие-либо другие списки. Это наш базовый корпус , где мы определяем конечный результат, который заканчивает рекурсию.