我以为我会和F#相处得很好,因为我在Haskell很体面,但我觉得我被一些简单的问题所困扰.我有一些简单的JSON解析器的解析代码,如下所示:
let rec parseObject tokens = function
| '"' :: cs -> parseString tokens cs
| ':' :: cs -> parseValue tokens cs
| '}' :: cs -> tokens, cs
...
let rec parseValue tokens = function
| c :: cs when Char.IsWhiteSpace(c) -> parseValue tokens cs
| '{' :: cs -> parseObject tokens cs
...
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为parseObject不知道parseValue.不能扭转他们或我会遇到相反的问题.那我该怎么办呢?
我正在尝试实现具有扩展解析功能的库.我决定使用fsyacc,因为我从大学就知道了.不幸的是我遇到了以下问题
我为我的语法(Head)的头部定义了一个类,并将其实现放在一个文件中.然后我将解析器定义为:
...
%start head
%type <Head> head
...
Run Code Online (Sandbox Code Playgroud)
Fsyacc生成seeparated模块(Parser).为了成功,必须按以下顺序编译:Head.fs Parser.fs
为了使这个库与您在.NET中可以找到的类似,我想向Head添加一个静态Parse方法.不幸的是,我需要使用Parser模块中的方法.
我知道这种类型的依赖关系可以通过' 和 '运算符来解决,但它只适用于在一个文件中定义的类型.
有没有其他方法可以创建相互依赖的类型,即使它们位于不同的文件中?我正在寻找声明/实现分离机制,就像在C/C++中那样,但我找不到任何东西.
我正在阅读在Haskell编程,在第8章中,作者给出了编写解析器的示例.完整的来源是:http://www.cs.nott.ac.uk/~gmh/Parsing.lhs
我无法理解以下部分:many 允许零个或多个应用程序p,但many1需要至少一个成功的应用程序:
many :: Parser a ? Parser [a ]
many p = many1 p +++ return [ ]
many1 :: Parser a ? Parser [a ]
many1 p = do v ? p
vs ? many p
return (v : vs)
Run Code Online (Sandbox Code Playgroud)
递归调用是如何发生的
vs <- many p
Run Code Online (Sandbox Code Playgroud)
vs是结果值many p,但很多p调用many1 p,many1在它的定义中都有一个do表示法,并且还有结果值v,并且vs,递归调用何时返回?为什么以下代码段可以返回[("123","abc")]?
> parse (many digit) "123abc"
[("123", "abc")]
Run Code Online (Sandbox Code Playgroud) 我正在读这本书,它谈到了类型类的定义Eq
在Eq中有两个函数==,/=它们实现为:
x == y = not (x /= y)
x /= y = not (x == y)
Run Code Online (Sandbox Code Playgroud)
书中说它们是相互递归的,函数的结果是在另一个函数的项目中.
我不明白的是我在相互递归中没有看到基本情况,我不明白为什么函数会停止并返回结果.
我试图用变体表示c ++中的PDF对象类型.PDF对象是以下之一:
BooleanIntegerRealStringNameStreamArray<Object>Map<Object, Object>如您所见,Object类型是相互递归的,因为Array类型需要声明Map类型,这需要声明Array类型.我怎么能在c ++中代表这种类型呢?如果变体不是最好的方式,那是什么?
以下是我到目前为止所尝试但由于std::unordered_map(我认为)http://coliru.stacked-crooked.com/a/699082582e73376e的要求而无法编译
如何将两个相互递归的函数相互更改为一个线性递归?我是否必须在单个方法中同时使用这两种方法?
在Haskell中,您可以执行以下操作:
Prelude> data Foo = Foo Bar; data Bar = Bar Foo
Run Code Online (Sandbox Code Playgroud)
你怎么能在OCaml做同样的事情?我试过了:
___
# type foo = Foo of bar;; type bar = Bar of foo;;
Error: Unbound type constructor bar
Run Code Online (Sandbox Code Playgroud)
甚至可以在OCaml中定义相互递归的数据类型吗?如果不是那么为什么?
将数据定义与let表达式进行比较:相互递归的数据类型对应于使用let rec(或者更适合type rec于缺少更好的短语).能够定义相互递归数据类型的优点是什么?我的foobar例子是微不足道的.您能想到相互递归数据类型的任何非平凡用法吗?
recursion ocaml haskell mutual-recursion algebraic-data-types
我正在学习函数,并决定制作一个循环,其中两个函数(在本例中为funcA和funcB)永远相互调用,但一段时间后它将停止执行。代码如下:
#include <iostream>
void funcA(); //forward declaration
//funcB calls funcA
void funcB()
{
funcA();
}
//funcA prints 1 and calls funcB again
void funcA()
{
std::cout<<1;
funcB();
}
//main calls funcB
int main()
{
funcB();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
返回值是-1073741571(0xC00000FD)。你能解释为什么会这样吗?
我遇到过这些关于相互递归的讨论,最初是在let表达式的上下文中,即 alet允许绑定相互引用而无需考虑顺序。(见这里。)然后我在维基百科中看到了这个讨论。这以 SML 中数据类型的形式给出了一个示例
datatype 'a tree = Empty | Node of 'a * 'a forest
and 'a forest = Nil | Cons of 'a tree * 'a forest
Run Code Online (Sandbox Code Playgroud)
我记得,这and是相互递归关系所必需的。它导致了 Haskell 中的这个版本
data Tree a = Empty
| Node (a, Forest a)
data Forest a = Nil
| Cons (Tree a) (Forest a)
Run Code Online (Sandbox Code Playgroud)
我对此有一个直观的理解,但语法很混乱,例如,SMLtree有
... Node of 'a * 'a forest
Run Code Online (Sandbox Code Playgroud)
这是一个元组,对吗?是的,我想我在 Haskell 翻译中看到了一个元组
... Node …Run Code Online (Sandbox Code Playgroud) 我有一个clojure程序,其中两个函数递归地相互调用:
(defn f1
...
(f2 ...)
)
(defn f2
...
(f1 ...)
)
Run Code Online (Sandbox Code Playgroud)
编译器发出错误f1.它说f2没有定义.有没有办法declare在clojure中使用函数.我可以验证递归实际终止.