Рекурсия по спискам - Haskell - PullRequest
0 голосов
/ 27 февраля 2019

В основном у меня есть это упражнение: вспомните синоним типа StudentMark с прошлой недели.Напишите рекурсивную функцию:

listMarks :: String -> [StudentMark] -> [Int]

, которая дает список оценок для конкретного учащегося;например:

listMarks "Joe" [("Joe", 45), ("Sam", 70), ("Joe", 52)] = [45,52]

Так я написал функцию:

type StudentMark = (String, Int)
listMarks :: String -> [StudentMark] -> [Int]
listMarks _ [] = []
listMarks std (x:xs)
  | std == fst x = snd x : listMarks (fst x) xs
  | otherwise = listMarks (fst x) xs

Это не работает, если строка из списка отличается от строки "std".Я хотел бы понять, почему и как я мог сделать эту работу?Спасибо!

1 Ответ

0 голосов
/ 27 февраля 2019

Easy Fix

Просто смените охрану | otherwise = listMarks std xs.Я также изменил бы его в вышеприведенном охраннике, так как | std == fst x = snd x : listMarks std xs как да, они равны, но это делает более ясным, чего вы хотите достичь.поэтому ваш код будет:

type StudentMark = (String, Int)
listMarks :: String -> [StudentMark] -> [Int]
listMarks _ [] = []
listMarks std (x:xs)
  | std == fst x = snd x : listMarks std xs
  | otherwise = listMarks std xs

Лучшие версии

Как видите, вы вызываете функцию всегда с одним и тем же первым аргументом, поэтому весьма вероятно, что вы можете написать более точную версию,Вот две быстрые идеи:

Понимание списка

Лично мое любимое, понимание списка очень гибкое и понятное:

listMarks' :: String -> [StudentMark] -> [Int]
listMarks' str marks = [m |(n,m) <- marks, n==str]

По сути, вы фильтруете список на основе первогоэлемент, а затем вы возвращаете второй.

Функции более высокого порядка

С функциями более высокого порядка map, filter и fold вы можете сделать столько же, сколько рекурсия и lcs, но часто выглядит аккуратнее.Вы хотите снова отфильтровать список по первому элементу, а затем вернуть второй.

listMarks'' :: String -> [StudentMark] -> [Int]
listMarks'' str =  map snd . filter (\(n,_) -> n == str)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...