Reputation: 1570
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.
Upvotes: 5
Views: 1983
Reputation: 85877
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
.
Upvotes: 11