Working on Brent Yorgey\'s 2013 UPenn class homework, the following newtype
exists:
newtype Parser a = Parser { runParser :: String -> Maybe (a
To apply g on a Parser f, i.e. composite g and f. However, as g is a general function,and f returns Maybe(a,String), we need to convert g to
Maybe(a,String)->d
. Given first::(a->b)->(a,c)->(b,c)
,then
first.Maybe :: Maybe(a->b,a->b)->Maybe(a,String)->Maybe(b,String)
first.Maybe :: (a->b)->Maybe(a,String)->Maybe(b,String)
first.Maybe g :: Maybe(a,String)->Maybe(b,String)
so
instance Functor Parser where
fmap g f = Parser $ fmap (first.Maybe g) . f
You're doing great.
If I just make a type synonym it might be clearer
type M a = Maybe (a,String)
You're right that you can use
fmap (first g) :: Maybe (a, String) -> Maybe (b,String)
-- :: M a -> M b
and combine it with
f :: String -> Maybe (a,String)
-- String -> M a
You just need to compose String -> M a
with M a -> M b
to get String -> M b
:
instance Functor (Parser) where
fmap g (Parser f) = Parser $ fmap (first g) . f
You asked if you could get a String from somewhere. Lambda will do that for you: \xs ->
can be read "give me a String xs
...", and you could apply f
to that String to get something of type Maybe (a,String)
. So you could also write:
instance Functor (Parser) where
fmap g (Parser f) = Parser $ \xs -> fmap (first g) (f xs)