WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Haskell · Intermediate · question 23 of 100

How do you handle state and side effects in Haskell?

📕 Buy this interview preparation book: 100 Haskell questions & answers — PDF + EPUB for $5

Handling state and side effects in Haskell often involves dealing with functional programming concepts such as purity and immutability. In this answer, I will explain two main concepts that deal with state and side effects in Haskell:

1. Using pure functions with explicit state passing

2. Using monads to abstract state changes and side effects

**1. Pure Functions and Explicit State Passing**

In Haskell, we usually work with pure functions to manage state. Pure functions are deterministic, meaning that they always return the same output for the same input, and they have no side effects. To manipulate state in Haskell, we typically pass the state explicitly as an input parameter and receive a new state as an output. Consider the following example:

type State = Int

addValue :: Int -> State -> State
addValue x state = state + x

This is a simple example of a stateful function in Haskell. It takes a value to add and a current state and returns the new state. You can use this function to modify the state multiple times.

For instance, let’s chain some state modifications:

initialState :: State
initialState = 0

main = do
    let newState1 = addValue 10 initialState
    let newState2 = addValue 5 newState1
    print newState2 -- Output: 15

However, the explicit state passing can become cumbersome when dealing with larger programs.

**2. Monads for State and Side Effects**

Monads provide an abstraction over state management and side effects in Haskell. A monad is a type class that defines a specific structure for computations. The ‘State‘ monad and the ‘IO‘ monad are two primary monads that deal with state and side effects in Haskell.

- *State Monad*: The ‘State‘ monad formalizes the pattern of explicit state passing and hides the state management details. Using the ‘State‘ monad, you can define stateful computations that will automatically thread the state.

Here’s the previous example, now using the ‘State‘ monad:

  import Control.Monad.State

  type MyState = Int

  addValue :: Int -> State MyState ()
  addValue x = do
      s <- get
      put (s + x)

To execute a ‘State‘ monad, you can use ‘runState‘ or ‘execState‘:

  main = do
      let finalState = execState (addValue 10 >> addValue 5) 0
      print finalState -- Output: 15

- *IO Monad*: The ‘IO‘ monad allows you to work with side effects in your program, like reading from or writing to files or working with network connections. The ‘IO‘ monad encapsulates side-effecting computations, marking it clear what parts of your program are impure.

For example, here’s a simple IO action that reads a line from the standard input and prints it:

  main :: IO ()
  main = do
      putStrLn "Enter a text: "
      text <- getLine
      putStrLn $ "You entered: " ++ text

In conclusion, Haskell provides mechanisms to handle state and side effects by either explicitly managing state through pure functions or using monads as abstract structures to handle state and side effects. The ‘State‘ monad and the ‘IO‘ monad are two commonly used monads in Haskell to manage state and side effects.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Haskell interview — then scores it.
📞 Practice Haskell — free 15 min
📕 Buy this interview preparation book: 100 Haskell questions & answers — PDF + EPUB for $5

All 100 Haskell questions · All topics