To obtain a sequential evaluation in a functional context, in JavaScript, I frequently use
const right = a => b => b;
const f = () => right(console.log("hi"))(true);
console.log(f());
This is somewhat similar to do
thread and much simpler to implement but only works in eager-evaluation languages such as JavaScript.
In Haskell, since the language works in a lazy-evaluation/call-by-need manner, the argument of a
will not be evaluated because it's not required in the lambda expression body.
So, I wonder what would be the simple smart approach to implement the right
function that works in the lazy evaluation. <- This is my #1 Question here.
There are Haskell wiki articles:
Sequential ordering of evaluation
The
seq
primitive, despite its name, is not required to evaluate its parameters in some predefined order, according to the Haskell 2010 Report. For parallel programming, sometimes a variant of seq is needed with such an ordering:
While we focus mainly on the implementation, our work has had some impact on the programming model: we identify the need for pseq as well as seq (Section 2.1), and we isolated a signficant difficulty in the "strategies" approach to writing parallel programs (Section 7). Runtime Support for Multicore Haskell; Simon Marlow, Simon Peyton Jones and Satnam Singh. Instead of two or more similar primitives with similar purposes, extend the existing seq primitive with the traditional ordering of evaluation for its parameters - first, then second; with the role of simple strictness-control being performed by a new primitive with a more appropriate name e.g.
amid
, in Strictness without ordering, or confusion.
and
Strictness without ordering, or confusion
As the Haskell 2010 Report does not specify any order of evaluation with respect to its parameters, the name of the primitive
seq :: a -> b -> b
is a misnomer.
Introduce the primitive
amid
, with the same (Haskell 2010 Report) requirements:
infixr 0 `amid`
primtive amid :: a -> b -> b
infixr 0 $!
($!) :: (a -> b) -> a -> b
f $! x = x `amid` f x
Actually, the function is exactly the same as my right
; however, what I don't understand is as I mentioned in lazy evaluation, since a
is not required in the function body, it shall not be evaluated. So what happens here? #2 Question
A code I think is
right = \a -> \b -> (const a . const b) 0
but, I don't know this one stably works.