Ограничение аргумента, чтобы быть Int - PullRequest
2 голосов
/ 03 апреля 2019

Я пытаюсь объявить функцию, числовым аргументом которой может быть только Int.

Я пишу функцию, которая отбрасывает каждый n элемент списка.Я использую арифметику по модулю, но функция mod будет принимать только тип Int, и я не могу понять, как гарантировать, что мое число удовлетворит это.

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

dropEvery :: (Num n, Eq n) => n -> [a] -> [a]
dropEvery m list = [list !! i | i <- [1 .. length list], i `rem` m /= 0]

Я запустил :info mod и заменил Num n на Real n, Enum n and Integral n (все ограничения, которые я вижу в выводе), но этовсе еще не гарантирует компилятору, что n будет Int.

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

1 Ответ

6 голосов
/ 03 апреля 2019

Вы просто должны использовать фактический тип Int вместо использования ограничений (Num n, Eq n). (Обратите внимание, что Haskell использует индексирование списка на основе 0, поэтому мне пришлось добавить -1 для его корректной работы.)

dropEvery :: Int -> [a] -> [a]
dropEvery m list = [list !! (i-1) | i <- [1 .. length list], i `rem` m /= 0]

main = print $ dropEvery 3 [1..20]

Попробуйте онлайн!

Если вы хотите избежать !!, вы также можете избежать явного определения длины списка, используя zip, который заменяет ваше понимание списка на

[ l | (l,i) <- zip list [0..], (i+1) `rem` m /= 0]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...