【问题标题】:why Alternative's some and many are infinite recursive functions in haskell为什么Alternative的一些和许多是haskell中的无限递归函数
【发布时间】:2016-09-24 09:13:55
【问题描述】:

我在 Haskell 中查看 Alternative typeclass,当我发布这个时,我正在 ghci 中使用它

some (Just 2)

挂了,我看了Alternative的源码,Alternative的一些很多默认定义是这样的:

some :: f a -> f [a]
some v = some_v
  where
    many_v = some_v <|> pure []
    some_v = (fmap (:) v) <*> many_v

-- | Zero or more.
many :: f a -> f [a]
many v = many_v
  where
    many_v = some_v <|> pure []
    some_v = (fmap (:) v) <*> many_v

很明显some_vmany_v 是间接无限递归的,它们不是根据empty&lt;|&gt; 定义的。

如果它们必须由实例定义,那么它们不应该有默认定义,对吧?并且由于Maybe 没有定义它们,因此我上面的声明被挂起,这对我来说似乎很奇怪,因为文档中没有提到它。

那么为什么他们被这样定义呢?有什么我想念的吗?

【问题讨论】:

  • many Nothingsome Nothing 工作正常。你希望some (Just 2) 做什么?
  • @melpomene Just [2]exception : unimplemented
  • Just [2] 在语义上是错误的。它必须是Just [2, 2, 2, 2, 2, 2, ...],但计算永远不会完成。
  • @melpomene hmmm 如果是Just [2,2,2,2,...] 那么take 2 &lt;$&gt; (some (Just 2)) 不会返回一些结果吗? (它挂在我身上)
  • 不,因为它实际上不能返回它(至少在当前定义下,它必须“运行操作”,直到 v 在某个时候变成 empty)。嗯。

标签: haskell recursion typeclass some-and-many alternative-functor


【解决方案1】:

Maybe 的 Alternative 实例如下:

instance Alternative Maybe where
    empty = Nothing
    Nothing <|> r = r
    l       <|> _ = l

它定义了empty(&lt;|&gt;),留下somemany 作为它们的默认实现。

Alternative 可能因值本身未包含的“外部原因”而成功或失败时,使用manysome 是有意义的。典型的例子是解析器:你尝试从输入流中重复解析整数,直到找不到整数并返回empty

但是对于Just 2,可以这么说,替代方案“总是成功”。该值没有任何外部因素可以使其“失败”并完成计算。所以它进入了一个无限循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 2011-10-31
    • 2012-01-18
    • 2011-08-16
    • 1970-01-01
    • 2016-09-11
    • 2020-12-28
    相关资源
    最近更新 更多