【问题标题】:What are Alternative's "some" and "many" useful for?Alternative的“一些”和“许多”有什么用?
【发布时间】:2013-08-07 16:23:03
【问题描述】:

AlternativeApplicative的扩展,声明empty<|>和这两个函数:

一个或多个:

some :: f a -> f [a]

零个或多个:

many :: f a -> f [a]

如果定义,somemany 应该是方程的最小解:

some v = (:) <$> v <*> many v

many v = some v <|> pure []

我找不到定义了somemany 的实例。 它们的含义和实际用途是什么?它们是否被使用过?仅仅从这个定义我无法理解他们的目的。

更新:我不是在问Alternative 是什么,而是somemany 是什么

【问题讨论】:

  • 虽然这里有一些不错的答案,但是这个问题可能与thisthisthis 重复
  • 它们就是它所说的:用于(例如)解析器的多种应用的组合器,将结果收集在一个列表中。我提供了易于遵循定义的基本示例。
  • @WillNess 谢谢,我没有考虑解析器。仍然让我感到困惑的是,为什么它们会包含在 Alternative 中,而这些函数对于基本类来说是未定义的。
  • 一个重复的问题得到了this very nice answer

标签: haskell applicative some-and-many alternative-functor


【解决方案1】:

在 STM Applicative 中,some 的意思是:继续尝试直到成功至少一次,然后继续尝试直到失败。 many 的意思是:尽可能多地这样做,直到失败。

【讨论】:

  • 很好,从来没想过!
【解决方案2】:

TL;DR: some 是一个或多个,many 是通过熟悉的 maximal munch 规则一遍又一遍地执行相同计算而收集的 0 个或多个结果。为了使这一点有意义,必须进行一些状态传递(和更改)以某种方式减少可能性域,否则它将无限重复。并且状态传递和解析密切相关。


一个基本的例子:with

import Control.Monad(Functor(..))
import Control.Applicative
import Data.Char

-- char string parser
newtype P a = P { runP :: String -> [(a,String)] }

-- runP (P p) s = p s

instance Functor P where
  -- fmap :: (a -> b) -> f a -> f b
  fmap f (P q) = P (\s -> [ (f y,ys) | (y,ys) <- q s])

instance Applicative P where
  -- pure :: a -> f a
  pure x = P (\s -> [(x,s)])
  -- (<*>) :: f (a -> b) -> f a -> f b
  P p <*> P q = P (\s -> [(x y, ys) | (x,xs) <- p s, (y,ys) <- q xs])

letter = P p where      -- sample parser
  p (x:xs) | isAlpha x = [(x,xs)]
  p _ = []

我们有

*Main Data.Char> runP letter "123"
[]
*Main Data.Char> runP letter "a123"
[('a',"123")]
*Main Data.Char> runP ( (:) <$> letter <*> pure []) "a123"
[("a","123")]
*Main Data.Char> runP ( (:) <$> letter <*> ((:)<$>letter <*> pure []) ) "a123"
[]
*Main Data.Char> runP ( (:) <$> letter <*> ((:)<$>letter <*> pure []) ) "ab123"
[("ab","123")]   -- NOT NICE ^^^^^^^^^^^^^^^^^^^^ -}

然后,用

instance Alternative P where
  -- (<|>) :: f a -> f a -> f a
  P p <|> P q = P (\s-> p s ++ q s)
  -- empty :: f a   -- the identity of <|>
  empty = P (\s-> [])

我们得到

*Main Data.Char> runP (many letter) "ab123"
[("ab","123"),("a","b123"),("","ab123")]
*Main Data.Char> runP (some letter) "ab123"
[("ab","123"),("a","b123")]

*Main Data.Char> runP (optional letter) "ab123"
[(Just 'a',"b123"),(Nothing,"ab123")]
*Main Data.Char> runP (optional letter) "123"
[(Nothing,"123")]

Prelude Main Data.Traversable> runP (sequenceA $ replicate 2 letter) "ab123"
[("ab","123")]               --  NICE  ^^^^^^^^^^^^^^^^^^^
-}

【讨论】:

  • 很好的解释!
  • 离题,元问题:我注意到您创建了缺少的 [haskell-alternative] 标签。前段时间,我也想过做同样的事情,甚至编制了一个我们可能想要添加的问题列表,但陷入思考是将 MonadPlus 和 Alternative 组合成一个标签(我的本能倾向)还是保留它们分开,以及如何命名标签(我最初想到的是 [monadplus-and-alternative])。我会很感激你对这些问题的看法——它可以帮助我最终下定决心:)
  • @duplode 我在那里使用了“haskell-”,因为“替代”本身似乎太模糊太笼统了。从这个角度来看,使用“monadplus-and-”确实没有需要。至于是否将它们结合在一起,您的列表中是否有许多需要两者 haskell-alternativehaskell-monadplus 的问题?如果没有,您可以定义后者并用它们两个标记那些少数。如果是,您可以将当前标签(通过简单地重新标记其当前的 11 个问题)重命名为 monadplus-and-alternativehaskell-monadplus-and-alternative。还是您的列表太短(续)
  • @WillNess 好主意,[alternative-functor] 听起来很棒!
  • @WillNess 重新标记完成!到目前为止,有 64 个问题,alternative-functor 进展顺利。在 39 个问题中,其中 14 个与 [alternative-functor] 共享,monadplus 感觉不那么可靠,尽管this gem of an unresolved controversy 可能已经值得入场了。
【解决方案3】:

我倾向于在 Applicative 解析器组合库中看到它们。

a :: Parser [String]
a = some (string "hello")

我看到manyparsers 中的default definitions of Parsing 中用于目的。

我认为 Parsec 作为解析器组合库的主要示例隐藏了 some/many 的使用,因为它重新定义了 (&lt;|&gt;) 之类的东西。

【讨论】:

    【解决方案4】:

    regex-applicative 包为RE(正则表达式)类型定义了a custom many method。正则表达式以及 RE 解析器的大小必须是有限的,因此对 somemany 使用默认定义会导致无限循环!幸运的是,many 只是经典的正则表达式*

    该包还包含some 的定义,但它看起来太像默认定义,没有什么有趣的。

    【讨论】:

      【解决方案5】:

      Will 提供了一个很好的例子来激励使用这些方法,但您似乎对类型类仍有误解。

      类型类定义列出了存在于类型类的所有实例的方法的类型签名。它还可能提供这些方法的默认实现,这就是 Alternative 的 somema​​ny 方法所发生的情况。

      为了成为有效的实例,必须为实例定义所有方法。因此,您发现没有专门somema​​ny 定义实例的那些使用 default 实现,并且它们的代码与您的问题中列出的完全相同。

      所以,为了清楚起见,确实定义了 somema​​ny 并且可以与所有 Alternative 实例一起使用,这要归功于默认定义与类型类定义一起给出。

      【讨论】:

      • 我明白这一切。澄清一下,somemany 的定义对于最基本的类型,例如 []Maybe 只是循环。所以虽然somemany对它们的定义是有效的,但是没有任何意义。
      • @PetrPudlák 我真的很喜欢this answer(谢谢,is7s)。
      • @WillNess 确实,这个答案非常好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-08
      • 2012-10-18
      • 2010-10-20
      相关资源
      最近更新 更多