2015-09-08 3 views
1

Я хочу сделать что-то вроде:Исчисление внутри рекурсивной функции

>enumerate ["banana", "potato", "ice"] 
[(1, "banana"), (2, "potato"), (3, "ice")] 

Я писал:

enumerate :: [String] -> [(Int, String)] 
enumerate [] = [] 

Как я могу контролировать/управлять INT счетчик? Есть ли способ сделать это без поддержки?

Обновление: Я знаю о Zip Функция. Но для изучения вопроса я хочу реализовать свою собственную функцию zip.

Update 2: В настоящее время Кодекс

Это то, что я сделал до сих пор, используя функцию поддержки. Учитывая это:

1) Я хочу реализовать свою собственную функцию zip;
2) Я не хочу, чтобы изменить функцию:-структуру

enumerate :: [String] -> [(Int, String)] 

enumerate :: [String]->[(Int,String)] 
enumerate [] = [] 
enumerate list = aux 1 list 


aux :: Int->[String]->[(Int, String)] 
aux _ [] = [] 
aux i (x:xs) = [(i, x)] ++ aux (i+1) xs 

Можно ли улучшить эту функцию? Поскольку я не хочу добавлять еще одну функцию к функции, я думаю, что функция поддержки - единственный способ пойти, правильно?

+2

Последний 'aux' выглядит хорошо. Для стиля я бы изменил '[(i, x)] ++ ...' на '(i, x): ...'. – chi

+0

вам не нужно 'enumerate [] = []', поскольку вы уже обрабатываете пустые списки в 'aux'. На самом деле вы можете просто написать 'enumerate = aux 1' – homam

+0

@homam и как функция aux распознает список? И Спасибо, что это сработало хорошо. Я думал, что могу просто использовать ':' в 'elem: list' – PlayHardGoPro

ответ

1

Существует уже функция, которая называется zip (zip :: [a] -> [b] -> [(a,b)]). Теперь для вашей функции вы можете просто передать список с 1,2,... в качестве первого аргумента и получить свой результат, например.

enumerate :: [String] -> [(Int, String)] 
enumerate = zip [1..] 

EDIT:

Если вы хотите реализовать свою собственную zip функцию, просто используйте:

zip' :: [a] -> [b] -> [(a,b)] 
zip' _ [] = [] 
zip' [] _ = [] 
zip' (x:xs) (y:ys) = (x,y):zip' xs ys 

Берет два списка ([a] и [b]) и поместить каждый элемент в кортеж. Края являются ядрами, когда один из списков пуст, вы возвращаете пустой список. В противном случае вы используете сопоставление шаблонов, чтобы первый элемент списка поместил их в кортеж и снова вызвал zip' с хвостом списка.

+0

Я знаю , Но я хочу реализовать один ... Только для вопросов изучения. Не могли бы вы дать мне руки? – PlayHardGoPro

+0

@PlayHardGoPro Итак, вы имеете в виду, что хотите реализовать свою собственную функцию 'zip'? – Rizier123

+1

Да ... Я хочу улучшить свои знания о рекурсии. Угадайте, что это путь. Я должен был сказать, что сначала пожалею об этом. Я обновлю вопрос – PlayHardGoPro

0

Как выяснены вы хотите реализовать свой собственный почтовый индекс:

zip' [] _ = [] 
zip' _ [] = [] 
zip' (x:xs) (y:ys) = (x,y) : zip' xs ys 
+1

всего несколько секунд слишком поздно :) – jakubdaniel

5

Не бойтесь написать функцию поддержки, на самом деле, рассматривают его как возможность: Почему произвольное начальное значение 1? Почему нет функции

>enumerateFrom 42 ["banana", "potato", "ice"] 
[(42, "banana"), (43, "potato"), (44, "ice")] 

После того, как у вас есть, что enumerate легко.

Edit: Либо дайте aux функцию реальное имя, ИМХО enumerateFrom хорошо или переместить его в пункте where, если вы знаете, что уже. И послушать chi, используйте x : ... вместо

+0

Проверь это, когда можешь, и дайте мне свой отзыв. – PlayHardGoPro

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