请考虑以下示例:
#lang racket
(match '(cat . doge)
[`(,a . ,b)
(match b
[a #t]
[_ #f])]
[_ "Not a pair"])
Run Code Online (Sandbox Code Playgroud)
如果我想匹配头部和尾部相同的对,我可能会写这个.这不起作用,因为第二个a绑定为一个新变量(并匹配任何东西).是否有任何模式形式允许我使用以前a从外部范围绑定的模式?
我知道这可以通过以下方式实现
(match* ('cat 'doge)
[(a a) #t]
[(_ _) #f])
Run Code Online (Sandbox Code Playgroud)
但我仍然想知道是否有办法从外部范围获取该变量(或者如果有理由不这样做,就像一些潜在的名称冲突问题或其他东西).
我正在尝试创建一类名为tableaux的对象,它们本质上是无符号整数向量的向量(它们就像矩阵,但行可以是不同的长度),我已经编写了一些算法.主要问题是我想从vector类继承这些对象的迭代器,我不知道如何.
我已经阅读了几个相关的问题和答案,而且我很容易std::vector<std::vector<unsigned int> >公开继承,但一致认为这是因为STL容器没有虚拟析构函数或其他原因.所以我决定尝试通过构图"继承".这是我正在努力实现的一个极小的例子:
#include <vector>
#include <iostream>
class tableau {
private:
std::vector<std::vector<unsigned int> > rep;
public:
using std::vector<std::vector<unsigned int> >::iterator;
void push_back(std::vector<unsigned int> const& new_row) {
rep.push_back(new_row);
}
};
int main() {
tableau t1;
std::vector<unsigned int> row1(10);
std::vector<unsigned int> row2(8);
t1.push_back(row1);
t1.push_back(row2);
tableau::iterator it = t1.begin();
for ( ; it != t1.end(); ++it) {
//display rows of tableau
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是g ++给了我错误:type' std::vector<std::vector<unsigned int> >'不是类型'tableau'的基类型.我刚刚开始学习C++,所以如果我做了一些愚蠢的事情,请保持温和.如果你想要更多我写的实际代码,请告诉我.
似乎如果我将一个集合写入一个文件,它不是一种可以作为一个集合轻松读回的格式.这是一个例子:
#lang racket
(let ([out (open-output-file "test.rkt" #:exists 'replace)])
(write (set 1 2 3 4 5) out)
(close-output-port out))
Run Code Online (Sandbox Code Playgroud)
这使得一个文件#<set: 1 3 5 2 4>,读者抱怨.还有就是邮件列表上相关的悬而未决的问题在这里.
我现在解决它的方法是将字符串打印"(set "到文件,然后是所有带空格的整数,然后是结束")".超级丑陋,我想尽可能使用读者.
说我有这个代码:
#lang racket
(define a
((? (x) x)
((? (y) y)
(? (z)
((? (w) w) z)))))
Run Code Online (Sandbox Code Playgroud)
我直观地知道这个lambda表达式(扩展性地)等于 (? (z) z)
我的问题是,如果a我想看看Racket在内部简化了多少功能,是否有办法打印出来.
更多信息:
默认情况下,如果我输入a解释器,我得到#<procedure:y>(这似乎提示了评估发生了多少).我可以将输出样式更改为"构造函数",然后结果是(lambda (a1) ...)更接近我想要的结果,但我仍然不知道正文中哪些是重要的部分.
我想有人可以通过对Racket的评估策略有更全面的了解来回答这个问题,但是如果显示程序主体是一件可能发生的事情,我仍然感兴趣.
假设我想在编译时替换所有出现的过程,例如所有出现的conswith 。我尝试了两种看起来很自然的选择:
(define-syntax \n (syntax-rules ()\n [(_ x y) (cons x y)]))\nRun Code Online (Sandbox Code Playgroud)\n\n如果我做类似的事情,这是可行的,但如果它不在应用程序位置,( 2 3)我就无法使用,所以如果我这样做,我会收到“错误语法”错误。(map \'(1 2) \'(3 4))
然后我想只替换标识符本身:
\n\n(define-syntax \n (\xce\xbb (_) #\'cons))\nRun Code Online (Sandbox Code Playgroud)\n\n现在它本身给了我#<procedure:cons>并(map \'(1 2) \'(3 4))给出了正确的答案,但是使用( 2 3)语法转换器正在获取所有参数并将整个表达式替换为cons,这不是我想要的。
我如何实现我想要的?有某种变压器可以做到这一点吗?
更新:当我输入最后一句话时,我调用了“橡皮鸭效应”并找到了make-rename-transformer我想要的东西。然而,文档说“这样的变压器可以手动编写”,而且我的两次尝试似乎都未能做到这一点。如何手动制作这样的变压器?(忽略文档中的要点make-syntax-transformer)
另外,我知道我可以使用(define cons),但那是运行时的整个额外函数调用。
我正在玩组合,在我的一个类中,我有一个包含下标运算符"[]"(来自std :: vector)的包装器.但是,当我说时,编译器(g ++)会生气this->[i].我通过使用(*this)[i]而解决了这个问题,但我认为这些是同义词.我错过了什么?这是一个抛出错误的小示例代码(我故意避免使用迭代器newmethod来简单地说明我的问题).
#include <vector>
#include <iostream>
class A {
private:
std::vector<int> rep;
public:
std::size_t size() { return rep.size(); }
int& operator[](std::size_t index) { return rep[index]; }
void newmethod();
A(size_t n, int m) : rep(n,m) {}
};
void A::newmethod() {
for (std::size_t i=0; i < (this->size()); ++i) {
std::cout << (*this)[i] << " ";
}
for (std::size_t i=0; i < (this->size()); ++i) {
std::cout << this->[i]; << " "; //Causes an error!
} …Run Code Online (Sandbox Code Playgroud)