haskellfunctional-programmingmonads

Understanding fmap with a monad


I have the following data type:

newtype Rep f a = Rep { runRep :: String -> f (String, a) }

The above type Rep f a is a stateful computation that takes a String as the initial state and produces a (String, a) as the result of the computation. f is a functor and the result of the computation is wrapped in the functor.

For the following function.

rep :: Functor f => Rep f a -> String -> f a
rep a s = fmap snd (runRep a s)

This function can be used to run a "Rep" computation on a string. However, I am not sure why runRep has to take a Rep f a as input as well as a String. Further for the line fmap snd (runRep a s), I am not sure whether the second element of the tuple will be returned wrapped in the functor or without it.

Any insights are appreciated.


Solution

  • runRep is something you defined in your record:

    newtype Rep f a = Rep { runRep :: String -> f (String, a) }

    The compiler will automatically construct a "getter" function for that with the name runRep. Such getter has the signature:

    someGetter :: Record -> TypeOfField

    For your runRep, it is thus:

    runRep :: Rep f a -> (String -> f (String, a))

    or less verbose:

    runRep :: Rep f a -> String -> f (String, a)

    The runRep is thus a function that indeed takes a Rep f a, and returns a function that takes a String and returns an f (String, a).

    I am not sure whether the second element of the tuple will be returned wrapped in the functor or without it.

    You will perform an fmap snd on the f (String, a). fmap snd has as signature:

    fmap snd :: Functor f => f (a, b) -> f b

    So you can indeed state that it will return the second item of the data wrapped in the functor. Although "wrapped" might not be the best word here.

    Note that if f ~ [], then you map on a list of 2-tuples, and you thus will return a list of all second items of that list.