实现Parser Functor

时间:2014-12-28 02:49:30

标签: haskell

在Brent Yorgey的2013年UPenn class作业中,以下newtype存在:

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

我正在尝试将Parser实施为Functor

给出以下first函数来帮助解决此问题:

first :: (a -> b) -> (a, c) -> (b, c)
first f (a, c) = (f a, c) 

我尝试了以下内容:

instance Functor (Parser) where
  fmap g (Parser f)  = Parser $ fmap (first g) (f . g)

然而,这不起作用。

据我了解,f的类型为String -> Maybe (a, String)。所以,我不知道如何apply Stringf才能获得Maybe (a, String)

获得Maybe (a, String)后,我相信我可以简单地运行fmap (first g) ...,其中...代表Maybe

请给我一个提示,了解如何获取Maybe (a, String)

由于fString来提供Maybe (a, String)类型,我不知道在哪里找到String参数。

2 个答案:

答案 0 :(得分:6)

你做得很好。

如果我只是制作一个类型的同义词,那可能会更清楚

type M a = Maybe (a,String)

你可以使用

fmap (first g) :: Maybe (a, String) -> Maybe (b,String)
--             :: M a -> M b

并将其与

结合使用
f :: String -> Maybe (a,String)
--   String -> M a

您只需要使用String -> M a撰写M a -> M b即可获得String -> M b

instance Functor (Parser) where
  fmap g (Parser f)  = Parser $ fmap (first g) . f

你问你是否可以从某个地方获得一个字符串。 Lambda将为您做到这一点:\xs ->可以读作“给我一个字符串xs ...”,您可以将f应用于该字符串以获得{{1}类型的内容}}。所以你也可以写:

Maybe (a,String)

答案 1 :(得分:0)

在分析器f上应用g,即复合g和f。但是,由于g是一般函数,并且f返回Maybe(a,String),我们需要将g转换为

Maybe(a,String)->d

。鉴于first::(a->b)->(a,c)->(b,c) ,然后

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)

所以

instance Functor Parser where
  fmap g f = Parser $ fmap (first.Maybe g) . f