5

I am reading the 2nd edition of the (great) book from Graham Hutton "Progamming in Haskell" (Cambridge Press).

Reading the State Monad section, I stumbled on a small task that I gave myself.

How could you rewrite the following using where instead of let?

type State = Int
newtype ST a = S (State -> (a, State))

instance Functor ST where
    -- fmap :: (a -> b) -> ST a  -> ST b
    fmap g st = S (\state -> let (x, s') = app st state in (g x, s'))

I tried variations around this code but it doesn't work:

instance Functor ST where
   -- fmap :: (a -> b) -> ST a  -> ST b
   fmap g st = S (\state -> (g x, newstate))
              where (x, newstate) = app st state

I know it's not useful per se, but I would like to know if and how it is possible.

1 Answer 1

11

let BINDINGS in EXPRESSION is an expression and can be used anywhere an expression is allowed.

where only attaches to declarations, not expressions. \state -> ... is not a declaration, so you can't attach where to it. You can't attach it to an outer declaration either because then state won't be in scope.

Possible solution:

instance Functor ST where
    fmap g st = S f
        where
        f state = (g x, s')
            where (x, s') = app st state

Instead of an anonymous function \state -> ... we have a local declaration f state = ..., to which we can attach a where clause that has access to state.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.