Программа постоянно переходит в состояние Edge независимо от ввода - Haskell - PullRequest
1 голос
/ 03 августа 2020

Я работал над проблемой, при которой у меня есть список кортежей, состоящий из songName, artistName и sales. Я должен получить либо количество продаж, используя имя песни и имя исполнителя, и если кортежа, содержащего эту информацию, нет в списке, я должен вернуть 0.

Я попытался решить эту проблему с помощью решение ниже:

testData :: [Sales]
testData = [("No Lie", "Sean Paul feat. Dua Lipa",  100),
        ("Yes Lie", "Sean Paul feat. Dua Lipa",  10),
        ("Fear & Delight", "The Correspondents",  120)]

findSales :: [Sales] -> String -> String -> Int
findSales ((track, artist,qty): xs) trackName artistName
     | track == trackName && artist == artistName = qty
     | otherwise = 0

Однако, когда я ввожу файл git запрос, например findSales testData "Yes L ie" "Sean Paul feat. Dua Lipa" , я ожидаю это будет включено в список кортежей и, следовательно, вернет 10, вместо этого программа вернет 0, крайний регистр.

Где я ошибаюсь, когда всегда возвращается крайний регистр?

И есть ли хороший инструмент / расширение, которое я мог бы использовать в VS Code, чтобы я мог легко отлаживать программу в будущем. Я пытался использовать Haskelly / Heskero, но мне не удалось заставить их работать при попытке их настройки.

1 Ответ

3 голосов
/ 03 августа 2020

Вы выполняете не рекурсию на хвосте списка. Таким образом, ваша программа проверяет только соответствие элемента first , а если нет, то переходит к otherwise. Таким образом, это означает, что если запрос соответствует первому элементу, он вернет этот элемент, а в противном случае вернет 0.

Таким образом, вы должны выполнить рекурсию в случае otherwise и вернуть 0 в случае, если список исчерпан:

findSales :: [Sales] -> String -> String -> Int
findSales <b>[]</b> _ _ = 0
findSales ((track, artist,qty): xs) trackName artistName
     | track == trackName && artist == artistName = qty
     | otherwise = <b>findSales xs</b> trackName artistName

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

findSales :: [Sales] -> String -> String -> Int
findSales xs trackName artistName = go xs
    where go [] = 0
          go ((track, artist,qty) : xs)
              | track == trackName && artist == artistName = qty
              | otherwise = <b>go xs</b>

или используйте функцию find :: (a -> Bool) -> [a] -> Maybe a :

import Data.List(find)
import Data.Maybe(maybe)

findSales :: [Sales] -> String -> String -> Int
findSales xs trackName artistName = maybe 0 (\(_,_,x) -> x) (<b>find</b> p xs)
    where p (track, artist,qty) = track == trackName && artist == artistName
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...