Hi,
While trying to learn lenses, ReaderT Design Pattern and Continuation Passing Style, I came across the following when I’m unsure about a parameter:
myLiftA2 :: (a -> b -> c) -> (Int -> IO a) -> (Int -> IO b) -> (Int -> IO c)
myLiftA2 f enva envb int = f <$> enva int <*> envb int
Summary
I don’t understand how the int
parameter can exist on the left-side
SOLVED: The type signature is the same as:
myLiftA2 :: (a -> b -> c) -> (Int -> IO a) -> (Int -> IO b) -> Int -> IO c
so the Int
was there the whole time: Without the int, we return a function that takes an int
and returns an IO c
→ with it applied, we return an IO c
I also notice this in the definition for a function to create a lens:
EDIT: expanded type of Lens
lens :: forall f. Functor f => (s -> a) -> (s -> a -> s) -> (a -> f a) -> s -> f s
lens getterFunc setterFunc sa s = setterFunc s <$> sa (getterFunc s)
where sa :: (a -> f a)
and s :: s
seem to appear out of nowhere on the left hand side.
EDIT2: Now given the expanded type signature this is more apparent and this one is also now solved for me!
I now have a new issue:
The type of most lens functions (getter, setter, traversal) tends to look like
type Getter/Setter s a = Functor/Applicative f => (a -> f a) -> (s -> f s)
which, in the case of getters apparently is equivalent to s -> a
but not in the case of setters.
In this case a getter can be a function that has a function of (a -> f a)
and a parameter s
and this should return an f s
so I’m not sure how we get s -> a
here.
Can anyone help explain this to me?
EDITS: Sorry for the edits, posted on reddit too and slowly working things out at the same time.