I have checked the possibility of duplicate question, and cannot find the exact solution.
I wrote some function chain code in JavaScript as below, and works fine.
var log = function(args)
{
console.log(args)
return function(f)
{
return f;
};
};
(log('1'))(log('2'))(log('3'))(log('4'));
//1
//2
//3
//4
I want to make this lazy evaluation.
Or to compose function.
var log = function(args)
{
var f0 = function()
{
return console.log(args);
};
return function(f1)
{
return function()
{
f0();
return f1;
};
};
};
var world = (log('1'))(log('2'))(log('3'))(log('4'));
console.log(world);
//should be just a function,
// but in fact
//1
//[function]
world();
//should be
//1
//2
//3
//4
// but in fact
// 2
Something is very wrong. Can you fix it?
Thanks.
This question is resolved, but there is further
async issue as shown in comment discussion
When we have
// unit :: a -> IO a
var unit = function(x)
{
return function()
{
return x;
};
};
// bind :: IO a -> (a -> IO b) -> IO b
var bind = function(x, y)
{
return function()
{
return y(x())();
};
};
// seq :: IO a -> IO b -> IO b
var seq = function(x, y)
{
return function()
{
return x(), y();
};
};
var action = function(x)
{
return function(y)
{
return y ? action(seq(x, y)) : x();
};
};
var wrap = function(f)
{
return function(x)
{
return action(function()
{
return f(x);
});
};
};
var log = wrap(console.log);
// -- runtime --
// HACK: when `world` is modified by passing a function,
// the function will be executed.
Object.defineProperties(window,
{
world:
{
set: function(w)
{
return w();
}
}
});
We also often want async chain reactions badly.
var asyncF = function(callback)
{
setTimeout(function()
{
for (var i = 0; i < 1000000000; i++)
{
};
callback("async process Done!");
}, 0);
};
var async = wrap(asyncF(function(msg)
{
world = log(msg);
return msg;
}));
Now,
world = (log(1))(async)(log(3));
//1
//3
//async process Done!
So far nice and smooth, now we try to use bind
world = (log(1))
(bind((async), (log(x))));
//should be
//1
//async process Done!
//3
//in fact
//ReferenceError: x is not defined
Could you modify to make this work, please?
one more about retrun x, y; multiple value
I don't understand
// seq :: IO a -> IO b -> IO b
var seq = function(x, y)
{
return function()
{
return x(), y();
};
};
as the library author mentions
Note that this is not possible in Haskell because one function can't return two results. Also, in my humble opinion, it looks ugly.
I agree, and don't know what this
return x(), y();
multiple return value.
I googled and searched here, but could not find an answer.
What is this??
(just in case, I will chose this hack for the syntax)
Thanks!
(log(1))will be evaluated before(log(4))during evaluatingvar world = (log('1'))(log('2'))(log('3'))(log('4'));, right? – Anurag Peshne Jan 16 at 10:21seqfunction does not return multiple values. In JavaScript when you writeexpressionA <comma> expressionBthe interpreter first evaluatesexpressionA, ignores its result, and then evaluatesexpressionB. The entire expression evaluates to the result ofexpressionB. For example,1, 2evaluates to2; andalert("Hello World!"), (1 + 2)evaluates to3after alertingHello World!. As MDN puts it: the comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.seq :: IO a -> IO b -> IO bignoresIO a. – Aadit M Shah Jan 17 at 2:54actionfunction, not theseqfunction. Theaction(x)returns eitherxor elseseq(x, y)(wrapped in a superfluous function for laziness) depending upon whether or not you pass the argumenty. It is not possible to implement theactionfunction in Haskell because in Haskell functions when supplied with the same arguments must return the same results. It is possible to implementseqin Haskell (it is called>>in Haskell).actionis a hack. Don't use it. – Aadit M Shah Jan 17 at 3:04