我在看 Alternative
haskell 中的 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_v
和 many_v
是间接无限递归的,它们不是根据 empty
定义的和 <|>
.如果它们必须由实例定义,那么它们不应该有默认定义,对吗?自
Maybe
没有定义它们我上面的语句被绞死,这对我来说似乎很奇怪,因为它没有在文档中提到。那么为什么他们是这样定义的呢?有什么我想念的吗?
最佳答案
Maybe 的 Alternative 实例如下:
instance Alternative Maybe where
empty = Nothing
Nothing <|> r = r
l <|> _ = l
它定义了
empty
和 (<|>)
, 离开 some
和 many
作为他们的默认实现。使用
many
和 some
当 Alternative
有意义时可能因值本身不包含的“外部原因”而成功或失败。典型的例子是解析器:你尝试从输入流中重复解析整数,直到找不到整数并且 empty
被退回。但与
Just 2
,可以这么说,替代方案“总是成功”。没有任何外部值可以使其“失败”并完成计算。所以它进入了一个无限循环。
关于haskell - 为什么替代的一些和许多是haskell中的无限递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39674640/