gpt4 book ai didi

parsing - Haskell `do` 符号如何知道当它不是由返回定义时要采用哪个值?

转载 作者:行者123 更新时间:2023-12-01 00:15:21 26 4
gpt4 key购买 nike

我有这个一元对象。

data Parser a = Parser (String -> Maybe (a, String))

instance Functor Parser where
-- fmap :: (a -> b) -> Parser a -> Parser b
fmap f (Parser pa) = Parser $ \input -> case pa input of
Nothing -> Nothing
Just (a, rest) -> Just (f a, rest)

instance Applicative Parser where
pure = return
(<*>) = ap

instance Monad Parser where
--return :: a -> Parser a
return a = Parser $ \input -> Just (a, input)

--(>>=) :: Parser a -> (a -> Parser b) -> Parser b
(Parser pa) >>= f = Parser $ \input -> case pa input of
Nothing -> Nothing
Just (a,rest) -> parse (f a) rest

我有一个 item 的定义我被告知“读取一个字符”,但我真的没有看到任何读取。

item :: Parser Char
item = Parser $ \ input -> case input of "" -> Nothing
(h:t) -> Just (h, t)

但好吧,好吧,也许我应该放松一下,“阅读”这个词的字面意思并与之相提并论。继续前进,我有

failParse :: Parser a
failParse = Parser $ \ input -> Nothing

sat :: (Char -> Bool) -> Parser Char
sat p = do c <- item
if p c
then return c
else failParse

这就是我很困惑的地方。什么被存储在变量 c 中?自 itemParser带参数 Char ,我的第一个猜测是 c正在存储这样一个对象。但经过一秒钟的思考,我知道现在不是 do符号有效,你没有得到 monad,你得到了 monad 的内容。很好,但是这告诉我 c那么函数

\ input -> case input of ""    -> Nothing
(h:t) -> Just (h, t)

但显然这是错误的,因为 sat 定义的下一行款待 c像一个角色。这不仅不是我所期望的,而且比我所期望的低了三个层次的结构!不是功能,不是 Maybe对象,它不是元组,而是 Just 的左坐标元组埋在函数里面!那个小角色是怎么在外面工作的?什么指示 <-提取monad的这一部分?

最佳答案

正如评论中提到的,<-只是do notation语法糖,相当于:

item >>= (\c->if p c 
then return c
else failParse)

好的,让我们看看什么是 c ?考虑 (>>=) 的定义
(>>=) :: Parser a -> (a -> Parser b) -> Parser b

或更易读的方式:
Parser a >>= (a -> Parser b)

现在,将其与上述表达式 item >>= (\c->if p c then return c else failParse) 匹配给:
Parer a = item


(a->Parser b) = (\c->if p c then return c else failParse) 

item有类型:
item :: Parser Char

所以,我们现在可以替换 a(>>=)通过 Char,给
Parser Char >>= (Char -> Parser b)

现在 \c->if p c then return c else failParse也有类型: (Char -> Parser b)
等等 c是一个字符,整个表达式可以扩展为:
sat p =
item >>= (\c->...) =
Parser pa >= (\c->...) = Parser $ \input -> case pa input of
Nothing -> Nothing
Just (a,rest) -> parse (f a) rest
where f c = if p c
then return c
else failParse
pa input = case input of "" -> Nothing
(h:t) -> Just (h, t)

关于parsing - Haskell `do` 符号如何知道当它不是由返回定义时要采用哪个值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53202036/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com