我正在查看haskell中的Alternative
类型类,当我发布这个时,我正在ghci中玩它
some (Just 2)
它挂了,我查看了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
没有定义它们,我上面的陈述被绞死了,这对我来说很奇怪,因为文档中没有提到它。
那他们为什么这样定义呢?有什么我想念的吗?
答案 0 :(得分:1)
Maybe的Alternative实例如下:
instance Alternative Maybe where
empty = Nothing
Nothing <|> r = r
l <|> _ = l
它定义empty
和(<|>)
,将some
和many
作为默认实现。
当many
因“外部原因”未包含在值本身中而成功或失败时,使用some
和Alternative
是有意义的。典型示例是解析器:您尝试从输入流重复解析整数,直到找不到整数并返回empty
。
但是对于Just 2
,备选方案“总是成功”,可以这么说。没有任何外部的价值可以使它“失败”并完成计算。所以它进入了无限循环。