Can a lazy estimate be implemented by a monadic type?

I am currently studying lazy pricing in conjunction with monads in Javascript and what use cases can develop from them. So I tried to implement a lazy type that implements a class like functor / monad. The corresponding constructor should be lazy in its arguments and in its result. Here is what I came up with:

// a lazy type

// (() -> a) -> () -> b
const Lazy = thunk => () => thunk();

// (b -> a -> b) -> b -> Lazy a -> b
Lazy.fold = f => acc => tx => f(acc) (tx());

// (a -> b) -> Lazy a -> Lazy b
Lazy.map = f => tx => Lazy(() => f(tx()));

// Lazy (a -> b) -> Lazy a -> Lazy b
Lazy.ap = tf => tx => Lazy(() => tf() (tx()));

Lazy.of = Lazy;

// Lazy (Lazy a) -> Lazy a
Lazy.join = ttx => ttx();

// (a -> Lazy b) -> Lazy a -> Lazy b
Lazy.chain = ft => tx => Lazy.join(Lazy.map(ft) (tx));

// recursive bind (or chain in Javascript)

// Number -> (a -> b) -> a -> Lazy b
const repeat = n => f => x => {
  const aux = m => y => m === 0
   ? Lazy(() => y)
   : Lazy.chain(aux(m - 1)) (Lazy(() => f(y)));

  return aux(n) (x);
};

// impure function to observe the computation

const inc = x => (console.log(++x), x);

// and run

console.log(repeat(5) (inc) (0)); // logs 1, 2, 3, 4, 5, () => thunk()
Run codeHide result

Now this obviously does not make sense, since the sequence of actions is not at all lazy. Lazy.joinjust starts the assessment prematurely. Therefore, the following questions arose:

  • - are sequences of monadic actions in Haskell always looking impatiently?
  • - a lazy assessment of the effect that cannot be realized by the monad in a strictly evaluated language?

, - , .

+4
3

, " ". , , "", . A -> State S B " A B". - A -> Delay B, , A "" . , - , Delay A -> Delay B.

, . , , . 1992 " " ( PDF). , , (CPS): . , " " / "" . CPS , . CPS , " " , . , CPS , , .

, Delay, , " " "" .

+3

, , , . Lazy.join

. :

// (() -> (() -> a)) -> (() -> a)
Lazy.join = ttx => Lazy(() => ttx()());
//                         ^^ this function prevents `ttx` from being evaluated immediately

( Lazy Lazy = id)

Haskell, ?

, , . , .

, ?

, .

, , re -. , .

+2

, ​​, .

, thunk, .. Lazy , .

join - , , , ! , , ; , .

return ( of ) ; return , .. Lazy.of(2) Lazy($ => 2)

, , . , ^ _ ^ , Lazy . runLazy. < 3

thunks $ => expr () => expr. JavaScript () s, (), . , Lazy($ => f()) ( ) , Lazy(() => f()). , , . , , .

, , () $ . ...

// data Lazy = Lazy (Unit -> a)
const Lazy = t => ({
  memo: undefined,
  // runLazy :: Lazy a -> Unit -> a
  runLazy () {
    return this.memo === undefined
      // console.log call just for demonstration purposes; remove as you wish
      ? (this.memo = t(), console.log('computed:', this.memo), this.memo)
      : this.memo
  },
  // chain :: Lazy a -> (a -> Lazy b) -> Lazy b
  chain (f) {
    return Lazy($ => f(this.runLazy()).runLazy())
  }
})

// Lazy.of :: a -> Lazy a
Lazy.of = x =>
  Lazy($ => x)
  
// repeat :: Int -> (a -> a) -> a -> Lazy a
const repeat = n => f => x =>
  n === 0
    ? Lazy.of(x)
    : Lazy.of(f(x)).chain(repeat (n-1) (f))

// m :: Lazy Number
const m = repeat (5) (x => x * 2) (1)

console.log('computations pending...')
// ...
console.log(m.runLazy()) // (1 * 2 * 2 * 2 * 2 * 2) => 32
console.log(m.runLazy()) // => 32
Hide result

, Lazy. Monoid empty, , , - - !

, chain f => join(map(f)), .

Functor

// map :: Lazy a -> (a -> b) -> Lazy b
map (f) {
  return Lazy($ => f(this.runLazy()))
}

// apply :: (a -> b) -> a -> b
const apply = f => x => f (x)

// ap :: Lazy (a -> b) -> Lazy a -> Lazy b
ap (m) {
  return Lazy($ => apply (this.runLazy()) (m.runLazy()))
}

// Lazy.of :: a -> Lazy a
Lazy.of = x =>
  Lazy($ => x)

// chain :: Lazy a -> (a -> Lazy b) -> Lazy b
chain (f) {
  return Lazy($ => f(this.runLazy()).runLazy())
}

// join :: Lazy (Lazy a) -> Lazy a
join () {
  return Lazy($ => this.runLazy().runLazy())
}

Monoid

// empty
empty () {
  // unsure on this one
}

// concat :: (Monoid a) => Lazy a -> Lazy a -> Lazy a
concat (m) {
  return Lazy($ => this.runLazy().concat(m.runLazy()))
}

, , , , /. !

+1

Source: https://habr.com/ru/post/1678280/


All Articles