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

Haskell · Guru · question 91 of 100

Can you explain the advanced usages of "Monadic Effects" in Haskell?

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

In Haskell, monads are the primary means of structuring effectful computations. In the context of programming, "effects" refer to things like IO, state manipulation, mutable references, exception handling, etc. Most of the time, you’ll use monads like ‘IO‘, ‘State‘, ‘Reader‘, ‘Writer‘, or ‘Except‘ for these purposes, but they can be combined in more advanced ways, as well.

Let’s take a closer look at some advanced usages of monadic effects in Haskell:

1. ‘Monad Transformers‘: Nested monadic effects can often be cumbersome to work with. Monad transformers aim to alleviate this issue by allowing you to "stack" monads, forming an overall composite monad structure that takes the individual monads into account. The basic idea is that you can take a monad ‘m‘, like ‘IO‘ or ‘State s‘, and ’lift’ other monads into the monad transformer stack, thus enabling the composition of various monadic effects.

An example using ‘StateT‘ transformer and ‘IO‘:

import Control.Monad.Trans.State
import Control.Monad.IO.Class

echo :: StateT Int IO ()
echo = do
    liftIO $ putStrLn "Please enter a number:"
    n <- liftIO readLn
    modify (+ n)
    s <- get
    liftIO $ putStrLn $ "Sum is: " ++ show s

2. ‘Extensible Effects‘: Extensible Effects is an approach to model advanced monadic effects by composing simple, orthogonal pieces into a unified, flexible whole. The key idea is to use a type-level list of effects (typically called ‘Eff‘) and a set of operations called "handlers" to directly represent and manipulate effectful computations. The ‘freer-simple‘ library in Haskell provides an implementation of extensible effects.

An example:

import Control.Monad.Freer
import Control.Monad.Freer.Reader
import Control.Monad.Freer.Writer

myProgram :: Member (Reader Int) r => Member (Writer String) r => Eff r Int
myProgram = do
    n <- ask
    tell ("Got value: " ++ show n)
    return $ n * 2

3. ‘Algebraic Effects‘: Algebraic Effects are a compositional programming model based on algebraic structures called "effects" and "handlers". These structures allow you to freely define, combine and interpret various effects in a modular way. The goal is similar to Extensible Effects, but with a more algebraic underpinning.

It’s great for defining custom effects and composing them with existing ones. The most common library for Algebraic Effects in Haskell is ‘polysemy‘.

Here’s an example of using ‘polysemy‘:

import Polysemy
import Polysemy.Input
import Polysemy.Output

doubleInput :: Members '[Input Int, Output Int] r => Sem r ()
doubleInput = do
    n <- input
    output (n * 2)

main :: IO ()
main = do
    let doubled = run
                . runInputArray [1, 2, 3, 4]
                . runOutputPure @Int
                $ doubleInput
    print $ fst doubled

These advanced usages of monadic effects enable more powerful and expressive programs while keeping their structure more maintainable and modular. They allow you to better control and reason about effectful computations in Haskell.

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