У меня была эта личная мантра: g «Избегайте if..else..else if
заявлений и используйте вместо них выражения», если я могу помочь. Это означает, что я могу использовать только троичное выражение, когда дело касается некоторого потока управления.
const decision = val => (if boolean evaluation with val is true) ? returnMe : elseReturnMe;
Теперь я ограничен только двумя возможными возвращаемыми значениями или операциями. Зачем мне это делать? Какова цель этой мазохистской мантры?
Это заставляет меня переосмыслить свой код и вынуждает меня разбивать свои функции на крошечные функции, которые специализируются на очень небольших операциях. Решения, которые примет моя программа, будут основаны только на логических оценках или оценках True / False.
Это упростит задачу, потому что теперь мне нужно только думать, будет ли это правда или ложь. Я думаю это также упростит другим программистам чтение моего кода. Поскольку он будет состоять из крошечных маленьких функций, которые имеют дело с конкретными операциями и простыми решениями.
Они сделали компьютеры с двоичным кодом. Я почти уверен, что смогу это сделать, по крайней мере, моя уверенность подсказывает мне.
Давайте попробуем это с последовательностью Фибоначчи. Определение, серия чисел, в которой каждое число (число Фибоначчи) является суммой двух предыдущих чисел. Самый простой - это серии 1, 1, 2, 3, 5, 8 и т. Д.
Сначала я реализую это с помощью if..else..else if
операторов.
const fibonacci = num => { if (num === 0) return 0; else if (num === 1) return 1; else return fibonacci(num - 1) + fibonacci(num - 2); }
Я знаю фигурные скобки. Давай, мне лень их печатать. Смирись с этим.
В Haskell это очень просто без if..else
. Это выглядит так,
fibonacci :: Integral a => a -> a fibonacci 0 = 0 fibonacci 1 = 1 fibonacci x = fibonacci(x - 1) + fibonacci(x - 2)
Это потому, что в Haskell есть сопоставление с образцом, а в Javascript этого нет. Это тема для отдельной статьи, просто развлечет ваше любопытство!
Как мне реализовать это в Javascript без сопоставления с образцом и без операторов if..else
?
Готовьтесь! Мне придется взломать свой код. Мне понадобятся некоторые функции, которые будут оценивать, равен ли он нулю или единице.
// isZero :: Int -> Bool const isZero = n => n === 0; // isOne :: Int -> Bool const isOne = n => n === 1;
Да, я мог бы объединить эти функции с дизъюнкцией, известной как логическое или. Но теперь у меня есть выбор использовать эти функции вместе или по отдельности.
Затем мне нужна функция, которая вернет ноль или единицу:
// zero :: Int -> Int const zero = n => isZero(n) ? 0 : n; // one :: Int -> Int const one = n => isOne(n) ? 1 : n;
Похоже, я все дальше ухожу от простого решения, потому что пишу все эти функции. Что, если я смогу их совместить? Позвольте мне сделать or
функцию. Пун входящий, дисфункция!
// or :: (a -> b) -> (a -> b) -> a -> b const or = (f, g) => x => f(x) || g(x);
Как мне это использовать? Позвольте мне использовать его с функциями zero
и one
.
// zeroOrOne :: Int -> Int const zeroOrOne = or(zero, one);
Посмотрим, смогу ли я уже построить с его помощью функцию Фибоначчи без if..else
операторов.
// fibonacci :: Int -> Int const fibonacci = n => n === 0 || n === 1 ? zeroOrOne(n) : fibonacci(n - 1) + fibonacci(n - 2); const result = fibonacci(6); console.log(result) // 8
Оно работает! но подождите ... Думаю, я все еще могу провести рефакторинг своей логической оценки. У меня есть эти маленькие функции выше, я думаю, что могу объединить их с or
// isZeroOrOne :: Int -> Bool const isZeroOrOne = or(isZero, isOne);
Ну наконец то,
const fibonacci = n => isZeroOrOne(n) ? zeroOrOne(n) : fibonacci(n - 1) + fibonacci(n - 2);
Никаких фактических
if..else
операторов в этой статье не использовалось.
P.S. Я выбрал фотографию выше, потому что думал, что она связана с рекурсией.