Is it possible to turn off lazy evaluation in Haskell?
Is there a specific compiler flag of library to facilitate this?
I wanted to try something new with a old program that I had written a while back, to see if I can improve performance.
Is it possible to turn off lazy evaluation in Haskell?
Is there a specific compiler flag of library to facilitate this?
I wanted to try something new with a old program that I had written a while back, to see if I can improve performance.
There are a number of ways to turn a lazy thing strict. You can:
seq
or its close relative ($!)
.BangPatterns
.More information here.
You can't turn off laziness, because the I/O system of Haskell depends on it. Without lazy evaluation this program would run into a busy loop without ever outputting anything:
main = forever (putStrLn "Hello!")
This is because forever c
is an infinite program. With lazy evaluation the program is calculated only as far as necessary to run the next instruction. If you turn off laziness, every function becomes strict, including (>>)
, which basically makes the forever
function diverge:
forever c = let cs = c >> cs in cs
However, you can add strictness annotations to constructors and patterns. When a function is strict, its argument is forced as part of the evaluation of the result independent of whether the argument is needed or not. This resembles eager evaluation.
In addition to what Daniel Wagner listed you may want to take a look at a similar question Is there a Haskell compiler or preprocessor that uses strict evaluation?.
The predominate suggestion is to use profiling tools and learn how to optimize Haskell as it is however, since most would consider it a different language with non-strict evaluation turned off.
There's a variant of Haskell called pH (http://csg.csail.mit.edu/projects/languages/ph.shtml) which uses eager evaluation while still providing non-strict semantics. The Haskell Report is careful to say that it's a non-strict language. Laziness is the obvious way to describe and, apparently, to implement non-strictness.
So, if your question is "Can we use a different evaluation system while maintaining non-strict semantics", you could look at pH. If your question is "Is there a version of Haskell which shares the surface syntax but is strict by default", I think it's covered by other answers.
You can enable the Strict
pragma in a module, which will cause everything to be strict by default.
The simple answer is no. The more complex answer is that the computational model upon which Haskell builds up and evaluates functions works in a lazy manner. As you will read in other answer there are ways to force evaluation of some functions earlier then normal, and it is occasionally adventitious to do so. But there is a large portion of valid Haskell which has no normal form. This includes the IO functions and a large amount of the standard prelude.
Conclusion: there is no more a way to turn of lazy evaluation in Haskell then there is a way to turn off pointer arithmetic in C or to turn off OO in Ruby of Java. I suspect that this is much farther then you though this question would take you. (There's no --strict
mode), but if you really want to see just how deep the rabit hole goes, "Implementing Lazy Functional Languages on Stock Hardware: The Spineless Tagless G-machine" by Simon Peyton Jones is an adventure worth having.
The strict-identity
package has a strict version of the Identity
monad.
You can find it here: https://hackage.haskell.org/package/strict-identity
The usage would look something like this:
foo = runStrictIdentity $! do
x <- f a b
y <- g x y
return $! x + y
Each time return
or bind >>=
is used, the two parts are evaluated using seq
, giving a reasonable guarantee of strictness provided your data structure isn't too deep. This works, for i.e. numbers and basic structures.