Как отобразить список заданного диапазона в haskell - PullRequest
0 голосов
/ 09 октября 2018

Как мне написать функцию, которая отображает заданный диапазон в списке в Haskell?Скажем, у меня есть функция:

dispRange l x y

, которая при заданных значениях:

dispRange [1,2,4,5,6,7] 0 3 

отображает все элементы с позиций от 0 до 3, таким образом, возвращаемый список будет:

[1,2,4,5]

Ответы [ 3 ]

0 голосов
/ 09 октября 2018

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

  1. Отрубить первый x элементов, рекурсивно вызывая вашу функцию и меняя аргументы соответствующим образом.
  2. Возвращает следующие y элементы, рекурсивно вызывая вашу функцию и изменяя аргументы соответствующим образом.

Ваш код будет выглядеть следующим образом:

dispRange :: …
dispRange … … … = []
dispRange … … … = dispRange … … …
⋮  ⋮  ⋮  ⋮  ⋮  ⋮  ⋮  ⋮  ⋮  ⋮
dispRange … … … = dispRange … … …

Итак, вопросы:

  • Какие типы аргументов и возвращаемое значение?
  • Как выглядят входы базовых и рекурсивных случаев для первого этапа выше?
  • Как выглядят входы базовых и рекурсивных случаев для второго этапа выше?

Теперь вы можете написать сигнатуру типа и шаблоны слева от знаков равенства (помните, что шаблоны выше имеют приоритет над шаблонами ниже, поэтому расположите их правильно).Затем вы можете написать реализацию каждого случая справа от знака равенства.


Если у вас возникли проблемы, другой способ - попытаться создать функцию, которая выполняет только первый этап.Затем попробуйте создать функцию, которая выполняет только второй этап.Затем используйте эти функции в вашей функции dispRange.

0 голосов
/ 09 октября 2018

dispRange использует список: l, начало: x и конец: y диапазона включительно.Возвращает элементы в этом диапазоне, если диапазон не отрицательный.

import Data.List ((\\))

dispRange :: Eq a => [a] -> Int -> Int -> [a]
dispRange l x y  
  | x <= y = (\\) <$> take (y + 1) <*> take x $ l
  | otherwise = []
0 голосов
/ 09 октября 2018

Мы можем использовать комбинацию drop :: Int -> [a] -> [a] и take :: Int -> [a] -> [a] для этого:

Длядиапазон i до j, мы сначала отбрасываем i элементов, а затем принимаем j-i+1 элементов (поскольку оба индекса включительно ,поэтому нам нужно добавить один).

Например:

dispRange :: [a] -> Int -> Int -> [a]
dispRange l i j = take (j-i+1) (drop i l)

Мы можем защититься от отрицательных чисел и j меньше i с:

dispRange :: [a] -> Int -> Int -> Maybe [a]
dispRange l i j | i < 0 || j < i = Nothing
                | otherwise = Just (take (j-i+1) (drop i l))
...