, , . let. , n = n, ( undefined) n . , .
, Racket , Racket let letrec. . let . , . letrec . , .
letrec , let, let . Haskell, ( , let letrec). , , Haskell, let. , :
-- Inserts value into slot1 or slot2
insert :: (Bool, Bool, Bool) -> (Bool, Bool, Bool)
insert (slot1, slot2, value) =
let (slot1', value') = (slot1 || value, slot1 && value)
(slot2', value'') = (slot2 || value', slot2 && value')
in (slot1', slot2', value'')
let Haskell , :
-- Inserts value into slot1 or slot2
insert :: (Bool, Bool, Bool) -> (Bool, Bool, Bool)
insert (slot1, slot2, value) =
let (slot1, value) = (slot1 || value, slot1 && value)
(slot2, value) = (slot2 || value, slot2 && value)
in (slot1, slot2, value)
, Haskell ? , . , , , . , .
, . , , . , , . , , , , - , . , ( JavaScript) , .
, . , , . - , . - let. , Racket let - , - -. , :
(let ([x 5])
(* x x))
let --:
((lambda (x) (* x x)) 5)
Haskell, (&):
import Data.Function ((&))
-- Inserts value into slot1 or slot2
insert :: (Bool, Bool, Bool) -> (Bool, Bool, Bool)
insert (slot1, slot2, value) =
(slot1 || value, slot1 && value) & \(slot1, value) ->
(slot2 || value, slot2 && value) & \(slot2, value) ->
(slot1, slot2, value)
, "" let:
const recur = (...args) => ({ type: recur, args });
const loop = (args, f) => {
let acc = f(...args);
while (acc.type === recur)
acc = f(...acc.args);
return acc;
};
const repeat = n => f => x =>
loop([n, f, x], (n, f, x) =>
n === 0 ? x : recur (n - 1, f, f(x)));
console.time('loop/recur');
console.log(repeat(1e6)(x => x + 1)(0));
console.timeEnd('loop/recur');
Hide resultloop. loop (&) Haskell, . , Haskell:
import Prelude hiding (repeat)
data Recur r a = Recur r | Return a
loop :: r -> (r -> Recur r a) -> a
loop r f = case f r of
Recur r -> loop r f
Return a -> a
repeat :: Int -> (a -> a) -> a -> a
repeat n f x = loop (n, f, x) (\(n, f, x) ->
if n == 0 then Return x else Recur (n - 1, f, f x))
main :: IO ()
main = print $ repeat 1000000 (+1) 0
, let . , let, letrec, , . Haskell , .