applicative <* 的一元等价物

发布于 2024-12-11 22:34:12 字数 1594 浏览 0 评论 0 原文

阅读安东尼的回复后<一href="https://stackoverflow.com/questions/7852484/parsec-parser-works-alright-but-could-it-be-done-better">一个与样式相关的解析器问题,我正在尝试说服自己编写单体解析器仍然可以相当紧凑。

因此,

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 ,意思是“序列但丢弃值并使用左侧提供的值”。

当然<<对于 liftM2 const 来说是一个糟糕的名字,它会表明 << 相当于 flip >>> 如果我们遵循与 >>==<< 相同的逻辑。

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

After having read Anthony's response on a style-related parser question, I was trying to convince myself that writing monadic parsers can still be rather compact.

So instead of

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

We can simply have:

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

Which is very similar to applicative version provided by Anthony:

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

...except for the <<! operator which is conceptually similar to <* which is defined as liftA2 const meaning "sequence but discard value and use value provided to the left".

Of course << would have been a bad name for liftM2 const, it would have suggested that << is equivalent to flip >> if we follow the same logic as >>= and =<<.

I don't find a "liftM2 const" under a single name. Is this because it is not that useful?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

唱一曲作罢 2024-12-18 22:34:12

我不太明白问题所在。每个 monad 也是一个 of applicative functor,因此您也可以简单地在 Monadic 表达式中使用 (*>)

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

I don't quite see the problem. Every monad is also an of applicative functor, so you can simply use (*>) in the monadic expressions as well.

(At the time of this answer (year 2011), Applicative was not a superclass of Monad, so it may have been necessary to add a corresponding class instance.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文