Nano Hash - криптовалюты, майнинг, программирование

Как отображать список с заданным диапазоном в haskell

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

dispRange l x y

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

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

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

[1,2,4,5]
08.10.2018

  • Что не работает с вашим подходом? 09.10.2018
  • Я пытался использовать условные выражения в понимании списков, но не могу найти правильный способ сделать это для диапазонов. 09.10.2018

Ответы:


1

Мы можем использовать комбинацию 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))
08.10.2018
  • Как добавить условные выражения, чтобы оба индекса не могли быть отрицательными, а первый индекс не мог быть больше второго и отображать сообщение об ошибке. Я только начинаю заниматься функциональным программированием, и синтаксис действительно сбивает с толку. 09.10.2018
  • @RyanThompson: вопрос в том, что вам следует делать в этом случае, часто в Haskell, если функция не является полной, ее делают полной, переписывая возвращаемый тип на Maybe [a] или Either String [a], чтобы указать, что вычисление может завершиться ошибкой. 09.10.2018

  • 2

    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 = []
    
    08.10.2018

    3

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

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

    Ваш код будет выглядеть так:

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

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

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

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


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

    08.10.2018
  • Как отрезать первые x элементов без использования встроенных функций? 09.10.2018
  • @RyanThompson Вы можете использовать сопоставление с образцом, например: chop n (x:xs) = … (где (x:xs) — это сокращение от x — это первый элемент списка, а xs — остальные элементы списка) для рекурсивного случая, а затем передать только xs обратно в функция рекурсивно, оставляя x за ее пределами. Это отсекает первый элемент списка. 09.10.2018
  • Я хотел объединить эти две функции, ChopF, которая отображает новый список, начиная с 'Переднего индекса', ChopF n (x:xs) | п == 0 = х: хз | в противном случае = чопF (n-1) хз. 11.10.2018
  • и ChopB, обрезка из индекса «Назад». ChopB nl n (x:xs) | n == 0 = x:nl | иначе = ChopB nl (n-1) xs. Однако у меня возникла проблема с объединением в новый список. любая помощь? 11.10.2018
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..