Search code examples
haskellfunctional-programmingmonadsstate-monad

Haskell State Monad Coordinate


I am trying to figure out how the state Monad works. I am trying to implement a function that gets two coordinates (x, y) and returns the x or y coordinate back. This should happen within the State Monad.

data Coordin = Coordin {x,y :: Float}

the functions that should be implemented they are looking like this:

getX :: State Coordin Float
getY :: State Coordin Float

How can this work out?

I have tried this:

newtype State s a = State { runState :: s -> (a,s) }  

getX:: State Coordin Float
getX = State $ \(x, y) -> (x, (x, y))

but getting this error message :

Couldn't match type ‘(Float, t0)’ with ‘Coordin’
    Expected type: State Coordin Float
      Actual type: State (Float, t0) Float
    In the expression: State $ \ (x, y) -> (x, (x, y))
    In an equation for ‘getX’: getX = State $ \ (x, y) -> (x, (x, y))

Solution

  • State $ \(x, y) -> (x, (x, y)) has the type State (Float,Float) Float, which is indeed equivalent (isomorphic) to State Coordin Float, but it's not literally the same type. The Coordin type must be unwrapped with the Coordin constructor, not with the tuple constructor!

    getX :: State Coordin Float
    getX = State $ \(Coordin x y) -> (x, Coordin x y)
    

    Alternatively, and preferrably, you can use the record field accessor:

    getX = x <$> get