Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where with lambda in haskell

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.

like image 516
godot Avatar asked Jan 01 '23 05:01

godot


1 Answers

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.

like image 189
melpomene Avatar answered Jan 08 '23 02:01

melpomene