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.
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.