Monadic相当于applicative< *

时间:2011-10-24 02:02:34

标签: haskell monads parsec applicative

Anthony's response上阅读a style-related parser question之后,我试图说服自己编写monadic解析器仍然可以相当紧凑。

所以而不是

reference :: Parser Transc
reference = try $ do string "#{"
                     a <- number
                     char ','
                     b <- number
                     char ','
                     c <- number
                     char '}'
                     return $ Outside (a,b,c)

我们可以简单地拥有:

reference3 :: Parser Transc
reference3 = liftM3 (((Outside .).) .  (,,)) 
             (string "#{" >> number <<! char ',') 
             number
             (char ',' >> number <<! char '}') where 
               (<<!) = liftM2 const

这与Anthony提供的应用版非常相似:

reference2 :: Parser Transc
reference2 = ((Outside .) .) . (,,) 
             <$> (string "#{" *> number2 <* char ',') 
             <*> number2 
             <*> (char ',' *> number2 <* char '}')

... <<!运算符除外,它在概念上类似于<*,其定义为liftA2 const,表示“序列但丢弃值和使用值提供给左侧”。< / p>

当然&lt;&lt;如果我们遵循与liftM2 const<<相同的逻辑,那么flip >>就相当于>>=,这可能是=<<的错误名称。

我没有在单个名称下找到“liftM2 const”。这是因为它不是 有用吗?

1 个答案:

答案 0 :(得分:10)

我不太明白这个问题。每个monad也是一个applicative functor,所以你也可以在monadic表达式中使用(*>)

(在本回答时(2011年),Applicative不是Monad的超类,因此可能需要添加相应的类实例。)