Skip to content

Instantly share code, notes, and snippets.

@purefunctor
Created June 11, 2020 13:54
Show Gist options
  • Save purefunctor/36ff916a020fe4610dc29640c85a3595 to your computer and use it in GitHub Desktop.
Save purefunctor/36ff916a020fe4610dc29640c85a3595 to your computer and use it in GitHub Desktop.

Lazy and Strict Maps in Haskell

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) 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment