Parsing 应用函子中的条件循环
假设Parsing 应用函子中的条件循环,parsing,haskell,applicative,Parsing,Haskell,Applicative,假设Parser x是解析x的解析器。这个解析器可能拥有一个manycombinator,它解析零次或多次出现的内容(当项目解析器失败时停止) 如果解析器形成一个monad,我可以看到如何实现它。如果Parser只是一个应用程序函子,我就不知道该怎么做了。似乎没有任何方法可以检查之前的结果并决定下一步要做什么(正是monad添加的概念)。我缺少什么?可选的类型类提供了多个组合器: class Applicative f => Alternative f where empty ::
Parser x
是解析x
的解析器。这个解析器可能拥有一个many
combinator,它解析零次或多次出现的内容(当项目解析器失败时停止)
如果
解析器
形成一个monad,我可以看到如何实现它。如果Parser
只是一个应用程序函子,我就不知道该怎么做了。似乎没有任何方法可以检查之前的结果并决定下一步要做什么(正是monad添加的概念)。我缺少什么?可选的类型类提供了多个组合器:
class Applicative f => Alternative f where
empty :: f a
(<|>) :: f a -> f a -> f a
many :: f a -> f [a]
some :: f a -> f [a]
some = some'
many = many'
many' a = some' a <|> pure []
some' a = (:) <$> a <*> many' a
optional :: Alternative f => f a -> f (Maybe a)
optional v = Just <$> v <|> pure Nothing
本质上,()
应该返回左侧值(如果它是真实的)。否则,它应该返回右侧值
解析器
是一种数据结构,其定义类似于可能
(和解析器组合器的概念基本相同):
如果解析失败,则返回Fail
值。否则将返回一个Ok
值。由于Fail pure[]
是pure[]
,这就是many
组合器知道何时停止并返回空列表的方式。many
是可选类的一种类方法,它表明一般的应用程序函子并不总是有many
实现。仅使用Applicative
。但是,Alternative
有一个功能,它为您提供了超出Applicative
之外的功能:
(<|>) :: f a -> f a -> f a
some
和many
的定义相似,但它们需要相互递归的函数
请注意,有一些Applicative
s不是Alternative
s。例如,您不能将标识
函子设置为备选
。您将如何实现empty
?对于我来说,关键是“决策”是使用
实现的。我不知道为什么我没有弄明白…这是否意味着替代品的力量等同于单子?@只有当你能把所有类型都列成表格时,意志才会。要了解原因,要使用
实现(=(ma->mb)
,基本上需要foldr()在列表上清空
,其中每个项目包括检查dependee结果是否与一个特定的a
值匹配,然后退化为mb
。因此,为了能够对所有a
选项执行此操作,您需要能够将所有a->mb
函数制成表格。
(<|>) :: f a -> f a -> f a
optional :: Alternative f => f a -> f (Maybe a)
optional v = Just <$> v <|> pure Nothing