- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的问题是关于 Graham Hutton 的书 Programming in Haskell 1st Ed .
在第 8.4 节中创建了一个解析器,我假设任何回答的人都有这本书或者可以在上面的链接中看到幻灯片 8 的链接。
称为item
的基本解析器描述为:
type Parser a = String -> [(a, String)]
item :: Parser Char
item = \inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)]
与do
一起使用定义另一个解析器p
(do
解析器)
p :: Parser (Char, Char)
p = do x <- item
item
y <- item
return (x,y)
相关的bind定义是:
(>>=) :: Parser a -> (a -> Parser b) -> Parser b
p >>= f = \inp -> case parse p inp of
[] -> []
[(v,out)] -> parse (f v) out
return
定义为:
return :: a -> Parser a
return v = \inp -> [(v,inp)]
解析
定义为:
parse :: Parser a -> String -> [(a,String)]
parse p inp = p inp
程序(do
解析器)获取一个字符串并选择第 1 个和第 3 个字符,并在元组中返回它们,字符串的其余部分在列表中,例如,"abcdef "
生成 [('a','c'), "def"]
。
我想知道 (f v) 输出
在 [(v,out)] -> 解析 (f v) out
返回一个解析器,然后应用于 out
。
f
在 do
解析器中是 item
和 item
取一个字符 ' c'
返回 [('c',[])]
?
它如何成为一个解析器,它如何将 out
作为参数?
也许我只是不明白(f v)
的作用。
此外,当再次调用 item
时,do
解析器如何每次“删除”返回值以对输入字符串的其余部分进行操作?
通过 do
解析器工作的对象是什么,它在每一步如何改变,通过什么方式改变?
最佳答案
f v
产生 Parser b
因为f
是 a -> Parser b
类型的函数和 v
是 a
类型的值.那么你调用parse
有了这个Parser b
和字符串 out
作为论据。
F in the 'do' parser is item
不,不是。让我们考虑一下解析器的简化(尽管现在有些无意义)版本:
p = do x <- item
return x
这将脱糖:
p = item >>= \x -> return x
所以>>=
的右操作数,即 f
, 是 \x -> return x
,而不是 item
.
Also how does the 'do' parser 'drop' the returned values each time to operate on the rest of the input string when item is called again? What is the object that works its way through the 'do' parser and how is it altered and each step and by what means is it altered?
当您应用解析器时,它会返回一个包含解析值的元组和一个表示输入其余部分的字符串。如果你看item
例如,元组的第二个元素将是 xs
这是输入字符串的尾部(即包含输入字符串除第一个字符之外的所有字符的字符串)。元组的第二部分将作为新输入提供给后续解析器(根据 [(v,out)] -> parse (f v) out
),这样每个后续解析器都会将前一个解析器生成的字符串作为其输出元组的第二部分作为输入(这将是 its 输入的后缀)。
回应您的评论:
When you write "p = item >>= \x -> return x", is that the equivalent of just the first line "p = do x <- item"?
不,它相当于整个 do
-block(即 do {x <- item; return x}
)。你不能翻译 do
- 像这样逐行阻止。 do { x <- foo; rest }
相当于 foo >>= \x -> do {rest}
,因此您将始终拥有 do
的其余部分-block 作为 >>=
的右操作数的一部分.
but not how that reduces to simply making 'out' available as the input for the next line. What is parse doing if the next line of the 'do' parser is a the item parser?
让我们来看一个调用 item
的示例。两次(这就像您的 p
,但没有中间项)。在下面我将使用 ===
表示 ===
上方和下方的表达式是等价的。
do x <- item
y <- item
return (x, y)
=== -- Desugaring do
item >>= \x -> item >>= \y -> return (x, y)
=== -- Inserting the definition of >>= for outer >>=
\inp -> case parse item inp of
[] -> []
[(v,out)] -> parse (item >>= \y -> return (v, y)) out
现在让我们将其应用于输入“ab”:
case parse item "ab" of
[] -> []
[(v,out)] -> parse (item >>= \y -> return (v, y)) out
=== Insert defintiion of `parse`
case item "ab" of
[] -> []
[(v,out)] -> parse (item >>= \y -> return (v, y)) out
=== Insert definition of item
case ('a', "b") of
[] -> []
[(v,out)] -> parse (item >>= \y -> return (v, y)) out
===
parse (item >>= \y -> return ('a', y)) out
现在我们可以展开第二个 >>=
同样的,我们打了拳头,最终得到('a', 'b')
.
关于parsing - Haskell:Graham Hutton Book Parsing(第 8 章): `parse (f v) out` 做什么,它是如何做的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52497671/
我发现在使用parse-node包时,不能再使用Parse.Cloud.httpRequest了。我也知道 Parse 的 Image 对象将不可用。 到目前为止,我已经能够用原生的替换一些 Pars
关闭。这个问题是opinion-based 。目前不接受答案。 已关闭 9 年前。 已锁定。这个问题及其答案是locked因为这个问题是题外话,但却具有历史意义。目前不接受新的答案或互动。 我有一个函
开源 Parse Server 是否包含用于配置新 Parse 实例的 Schema API?我试图消除手动创建应用程序的需要。 这是通过 Parse.com 提供的架构 API http://blo
我想从我的云代码发出一个 http 请求,该请求在我的客户端被调用。 最佳答案 一开始我发现这有点令人困惑,所以希望这会有所帮助。 在您的云代码中main.js Parse.Cloud.define(
这部分代码应该读入两个或更多数字(省略主 io 函数),然后是一个“+”来给出总和。使用有理数是因为稍后我将进行乘法和其他此类操作。 data Expression = Number Rationa
我似乎找不到任何关于此的官方信息:Does Parse.Config work on Parse Server?它曾经在 Parse.com 上工作,但是当我尝试迁移到 Parse.Server 时,
我正在尝试找到使用 Parse.com 添加密码要求的最佳程序。似乎最简单的方法是在保存用户数据之前使用云功能执行。我唯一的警告是,只有当密码与数据库中存储的密码不同或者用户不存在于数据库中时,我才想
我是 android 开发、应用程序开发和一般开发的初学者,我正在尝试为我的 android 应用程序设置后端数据库。我决定使用一个名为 back4app 的服务,以便获得更加用户友好的数据库体验,因
我目前正在尝试将 Facebook 登录功能添加到我的应用程序。 根据Android文档,当我添加 compile 'com.parse:parsefacebookutils-v4-android:1
我正在尝试使用 Rebol 2/3 从字符串中解析货币值,货币值的格式为: 10,50 欧元或 10,50 欧元 我在浏览了所有 PARSE 文档后想出了这段代码,我可以在 Red 中找到它,但在 R
代码: DateTimeFormat dateFormat = DateTimeFormat .getFormat("EEE MMM dd HH:mm:ss zzz y
我不再在 Parse 上看到用于导入 JSON 或 CSV 文件的导入按钮。他们是否将其移动到某个地方,或者不再可能导入这些文件类型? 最佳答案 官方原因是这样的: “[导入类按钮] 几天前被删除,因
我正在使用 PHP 从我的服务器检索一些数据。我想在 javascript 应用程序中使用这些数据,所以我正在做这样的事情: var polylines = ; $polylines 只是一个 PHP
我已经开始使用 .NET 4 System.Numerics.BigInteger Structure我遇到了一个问题。 我正在尝试解析一个包含无符号(正数)的十六进制数字的字符串。我得到一个负数。
我正在使用 PHP 从我的服务器检索一些数据。我想在 javascript 应用程序中使用这些数据,所以我正在做这样的事情: var polylines = ; $polylines 只是一个 PHP
在 Go 中,尝试将字符串转换为 time.Time 时,使用时间包的 Parse 方法不会返回预期结果。似乎问题出在时区。我想更改为 ISO 8601 结合 UTC 日期和时间。 package m
我正在尝试将此字符串模式 "4-JAN-12 9:30:14" 解析为 time.Time。 尝试了 time.Parse("2-JAN-06 15:04:05", inputString) 和许多其
从云代码和解析开始。使用this . 如何删除所有 Parse 项目以便开始创建新项目?我收到以下错误: “您想要创建一个新应用程序,还是将 Cloud Code 添加到现有应用程序中?输入“(n)e
我在解析云代码时有这个功能: Parse.Cloud.define("testfunction", function(request, response) { var username = r
最近,我在 parse.com 上做了一些测试。我现在面临在后台作业中使用 Parse.Object.saveAll 的问题。 从 parse.com 的文档来看,后台作业可以运行 15 分钟。我现在
我是一名优秀的程序员,十分优秀!