Ответ 1
Вы можете использовать функцию subtract
вместо -
, если вы хотите вычитать вправо:
map (subtract 1) [1..5]
Если мы хотим отобразить функцию, которая увеличивает каждый элемент диапазона на 1, мы могли бы написать
map (\x -> x + 1) [1..5]
но я думаю, что большинство людей просто поедут за
map (+1) [1..5]
вместо этого. Но это, очевидно, не работает с (-1), поскольку этот отрицательный.
Итак, первое, что пришло в голову, было
map (+(-1)) [1..5]
что будет иметь смысл, учитывая, как вычитание определено в Prelude (x - y = x + negate y
), но выглядит немного странно для меня. Затем я придумал
map (flip (-) 1) [1..5]
Это как-то выглядит лучше для меня, но, может быть, это слишком сложно.
Теперь я знаю, что это неважно, но мне интересно, не хватает ли я более очевидного способа написать это? Если нет, какой из двух способов вы бы предпочли? Я просто спрашиваю, потому что часто это небольшие детали, подобные этому, делают ваш код более идиоматичным и, следовательно, приятным для других разработчиков, которые должны его прочитать.
Решение
Теперь, когда я получил пару ответов, я думаю, что мой личный фаворит
map (subtract 1) [1..5]
за которым следует
map pred [1..5]
в основном потому, что первый из них действительно ясен, и никто не должен угадывать/искать то, что означает pred
(предшественник).
Вы можете использовать функцию subtract
вместо -
, если вы хотите вычитать вправо:
map (subtract 1) [1..5]
Так как -
является как вычитанием инфикса, так и префиксом negate, вы не можете использовать синтаксис (*x)
(где * - инфиксный оператор и x значение) для -
. К счастью, Prelude поставляется с negate
и subtract
, что соответствует \x -> -x
и \x y -> y-x
соответственно, так что вы можете использовать те, где вам нужно различать эти два.
Я думаю, что map (\x -> x - 1) [1..5]
лучше передает намерение программиста, так как нет никаких сомнений в том, что вычитается из чего. Я также нашел ваше первое решение, map (+(-1)) [1..5]
, легко читаемое.
Мне не нравится subtract
, потому что он смехотворно назад. Я предлагаю
minus :: Num n => n -> n -> n
minus = (-)
infixl 6 `minus`
Затем вы можете написать
map (`minus` 1) [1..5]