Is it possible to implement (*)
with least-strict semantics in Haskell (standardized Haskell preferred, but extensions are OK. Using compiler internals is cheating
Yes, but only using constrained impurity.
laziestMult :: Num a => a -> a -> a
laziestMult a b = (a * b) `unamb` (b * a)
here unamb is Conal Elliott's "pure" variant of amb
. Operationally, amb
runs two computations in parallel, returning which ever comes first. Denotationally unamb
takes two values where one is strictly greater (in the domain theory sense) than the other, and returns the greater one. Edit: also this is unamb, not lub, so you need to have them equal unless one is bottom. Thus, you have a semantic requirement that must hold even though it can't be enforced by the type system. This is implemented as essentially:
unamb a b = unsafePerformIO $ amb a b
much work goes into making this all work correctly with exceptions/resource management/thread safety.
laziestMult
is correct if *
is commutative. It is "least strict" if *
is non strict in one argument.
For more, see Conal's blog