Implementing Parser Functor

后端 未结 2 349
别那么骄傲
别那么骄傲 2021-01-19 08:56

Working on Brent Yorgey\'s 2013 UPenn class homework, the following newtype exists:

newtype Parser a = Parser { runParser :: String -> Maybe (a

相关标签:
2条回答
  • 2021-01-19 09:53

    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
    
    0 讨论(0)
  • 2021-01-19 09:55

    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)
    
    0 讨论(0)
提交回复
热议问题