There are many ways to implement mutable state in Haskell, but to begin with, we’ll use the way that’s most similar to the sicp solution: IORefs. An IORef is a mutable variable, like in any other programming language.2 The only major difference is that we need a bit of extra machinery to read from it, because it’s designed so that we cannot accidentally read from it in pure code. (That would make the code impure, after all.) We define a type Wire, which starts out with its signal Low, and with an empty list of action procedures. The idea of action procedures comes from the sicp implementation of this code; action procedures are subscribers to the signal on this wire, and they will be invoked whenever the signal changes. Action procedures will be installed by components connected downstream of this wire, so those components can update themselves when the wire value changes. In[1]: data Signal = Low | High deriving (Show, Eq, Ord, Bounded) data Wire = Wire { action_procedures :: IORef [IO ()] , signal_value :: IORef Signal } make_wire = do initial_procs <- newIORef [] initial_signal <- newIORef Low pure (Wire initial_procs initial_signal) We can get the signal from a wire by reading the mutable variable holding its current signal. In[2]: get_signal (Wire _ signal) = readIORef signal To set a signal on a wire we write to the mutable variable. If this causes a state change of the wire, we’ll also run the installed action procedures to let downstream components know.3 This is the observer pattern, in case it sounds familiar. In[3]: set_signal (Wire procs signal) new_value = do current <- readIORef signal when (new_value /= current) $ do writeIORef signal new_value actions <- readIORef procs sequence_ actions Finally, we have a method on the wire that lets downstream components install new action procedures. To ensure wires are initialised with the proper value when components are connected, we immediately run all action procedures we install. In[4]: add_action (Wire proc...
First seen: 2026-07-27 12:27
Last seen: 2026-07-27 13:28