import Control.Concurrent
import Data.Map.Lazy as LM
import Data.Map.Strict as SM
import System.IO.Unsafe
lm = LM.fromList
[ (x , unsafePerformIO (threadDelay 1000000 >> putStr " Slept " >> return 42))
| x <- [1 .. 5]
]
sm = SM.fromList
[ (x , unsafePerformIO (threadDelay 1000000 >> putStr " Slept " >> return 42))
| x <- [1 .. 5]
]
GHCi, version 8.8.2: https://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( maps.hs, interpreted )
Ok, one module loaded.
*Main> lm
fromList [(1, Slept 42),(2, Slept 42),(3, Slept 42),(4, Slept 42),(5, Slept 42)]
*Main> sm
fromList Slept Slept Slept Slept Slept [(1,42),(2,42),(3,42),(4,42),(5,42)]
*Main>
lm
and sm
are declared to be lazy and strict maps that contain key/value pairs of Integers and IO Actions (resulting to Integers) forcefully executed through unsafePerformIO
. lm
and sm
have different strategies for the evaluation of values in order to facilitate printing. In the case of lm
where the values are evaluated as they are needed, the side effect of printing Slept
to the screen is intertwined with the side effect of printing the contents of lm
. On the other hand with sm
where the values have to be evaluated before anything else, the side effect of printing Slept
is done before the side effect of printing the contents of sm
.
A near-equivalent in Python would be:
import time
def io_action():
time.sleep(1)
print(" Slept ", end="")
return 42
# Use a generator expression for laziness.
print("Lazy: ", end="")
for i in ((x + 1, io_action()) for x in range(5)):
print(i, end="")
# Use a list comprehension for strictness.
print("Strict: ", end="")
for i in [(x + 1, io_action()) for x in range(5)]:
print(i, end="")
Lazy: Slept (1, 42) Slept (2, 42) Slept (3, 42) Slept (4, 42) Slept (5, 42)
Strict: Slept Slept Slept Slept Slept (1, 42) (2, 42) (3, 42) (4, 42) (5, 42)