Подсчитать количество значений во вложенном списке, которые больше и меньше определенных значений - PullRequest
1 голос
/ 26 сентября 2019

Я работаю над функцией для домашней задачи, которая подсчитывает количество значений в списке, для которых значения больше v1 и меньше v2.Я собрал что-то, что работает, но только в конкретном случае.Когда я пытаюсь что-то еще, я получаю ошибку

*** Исключение: неисчерпывающие шаблоны в функции countInRange

Эта функция должна вызываться на getInRange,getInRange просто возвращает значения из списка, которые больше v1 и меньше v2.Вот как это выглядит.

rangeHelper v1 v2 x | x > v1 && x < v2 = True
                    | otherwise = False

getInRange :: Ord a => a -> a -> [a] -> [a]
getInRange v1 v2 iL = filter(rangeHelper v1 v2) iL

count iL = sum (map (const 1) iL)

countInRange :: Ord a => a -> a -> [[a]] -> Int
countInRange v1 v2 [iL] = count ((getInRange v1 v2) iL)

Если бы я позвонил

countInRange 3 10 [[4,5,6]]         -- works, prints 3
countInRange 3 10 [[1,2], [4,5,6]]  -- error: non exhaustive patterns

Ответы [ 2 ]

3 голосов
/ 26 сентября 2019

Если бы мы упростили вашу функцию даже до

countInRange v1 v2 [ iL ]  =  0

, мы бы по-прежнему наблюдали такое же поведение:

countInRange 3 10 [ [4,5,6]        ]   -- returns 0
countInRange 3 10 [ [1,2], [4,5,6] ]   -- ***Error: Non-exhaustive patterns

Вы видите проблему здесь?

2 голосов
/ 26 сентября 2019

Ваша функция countInRange ожидает только список, содержащий один список.Когда вы пишете countInRange v1 v2 [iL], вы определяете его для соответствия шаблону только тогда, когда ваш список содержит один элемент с именем iL.Вы также можете использовать count = length

. Вы можете решить эту проблему, определив ее следующим образом:

countInRange v1 v2 xs  = sum (map (length.filter (rangeHelper v1 v2)) xs)
-- or
countInRange v1 v2     = sum.map (length.filter (rangeHelper v1 v2))
...