【发布时间】:2014-08-30 23:59:28
【问题描述】:
我正在处理Brent Yorgey Haskell course,但在为 Applicative 定义一个好的实例时遇到了麻烦。解析器定义如下:
newtype Parser a = Parser { runParser :: String -> Maybe (a, String) }
该函数接受一个字符串,解析一定数量的输入,并返回一个 Maybe 元组,其中第一个值是解析器的类型,其余的是字符串的未解析剩余部分。例如,这是一个正整数解析器:
posInt :: Parser Integer
posInt = Parser f
where
f xs
| null ns = Nothing
| otherwise = Just (read ns, rest)
where (ns, rest) = span isDigit xs
任务是为 Parser 创建一个 Applicative 实例。我们从一个 Functor 实例开始(我认为这相对简单):
first :: (a -> b) -> (a,c) -> (b,c)
first f (a, c) = (f a, c)
instance Functor Parser where
fmap f p = Parser f'
where f' s = fmap (first f) $ (runParser p) s
然后我尝试了 Applicative:
collapse (Just (Just a)) = Just a
collapse _ = Nothing
extract (Just a, Just b) = Just (a,b)
extract _ = Nothing
appliedFunc :: Parser (a->b) -> Parser a -> String -> Maybe (b, String)
appliedFunc p1 p2 str = extract (f <*> fmap fst result2, fmap snd result2)
where result1 = (runParser p1) str
f = fmap fst result1
result2 = collapse $ fmap (runParser p2) $ fmap snd result1
instance Applicative Parser where
pure a = Parser (\s -> Just (a, s))
p1 <*> p2 = Parser (appliedFunc p1 p2)
...糟糕。所以我的问题是,我怎样才能让我的 Applicative 实例更干净,更不容易阅读?我觉得这个问题有一个简单的答案,但我还不能完全理解这些类型。
【问题讨论】:
标签: haskell functor applicative