我打开草稿,移至其索引,在该页面搜索单词lambda,然后继续进行连续匹配,直到第 5 场比赛时,我发现
纽带
詹姆斯·邦德,[expr.prim.lambda.capture]
那是什么?
我知道这严格来说不是一个关于代码的问题,但那东西是标准草案的草案!此外,詹姆斯·邦德出现在索引中“完全关于语言”的旁边[expr.prim.lambda.capture]
。不确定我是否应该添加语言律师标签。
我知道草稿开头的注释如下:
注意:这是一个早期草案。众所周知,它是不完整和不正确的,并且有很多错误的格式。
但这正是重点:索引中的詹姆斯·邦德是一个“打字错误”(好吧,一个恶作剧),或者也许我只是不知道一些非常重要的事情?
根据评论,这似乎是标准中并不少见的笑话。
后续问题(我不敢单独问)是:“这些笑话是否保留在实际标准中?”
长话短说,我正在观看Simon Peyton-Jones 的演讲,当时21:41他引用了一段话:
\n\n\n我正在解决一个错误,感到沮丧,并在 ghci\xe2\x80\xa6 中输入“修复错误”
\n
所以我尝试了。
\n结果:
\n\xce\xbb> import Data.Function -- here is fix\n\xce\xbb> fix error\n"*** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: …
Run Code Online (Sandbox Code Playgroud) 假设您有以下代码:
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::vector<std::string> First{"example", "second" , "C++" , "Hello world" };
std::vector<std::string> Second{"Hello"};
First.swap(Second);
for(auto a : Second) std::cout << a << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
想象一下向量不是std::string
,但类:
std::vector<Widget> WidgetVector;
std::vector<Widget2> Widget2Vector;
Run Code Online (Sandbox Code Playgroud)
用该std::vector::swap
方法交换两个向量是否仍然安全:WidgetVector.swap(Widget2Vector);
或者它会导致 UB?
Scott Meyers 在 Effective Modern C++, Item 30 page 210 中写道,有
无需
static const
在类中定义完整的数据成员;仅声明就足够了,
那么示例代码是
class Widget {
public:
static const std::size_t MinVals = 28; // MinVals' declaration;
...
};
... // no defn. for MinVals
std::vector<int> widgetData;
widgetData.reserve(Widget::MinVals); // use of MinVals
Run Code Online (Sandbox Code Playgroud)
我确信这static const std::size_t MinVals = 28;
既是声明又是定义,因为它给了一个值MinVals
,但评论似乎声称这只是一个声明;第二条评论实际上声称没有定义。代码后面的文字,确实是读
MinVals
缺乏定义。
这证实这static const std::size_t MinVals = 28;
不是一个定义,所以我有点困惑。
cppreference对我帮助不大(我的粗斜体):
如果声明
static
了整型或枚举类型的数据成员(而不是),则可以使用初始化器对其进行初始化,其中每个表达式都是常量表达式,就在类定义中:const
volatile
Run Code Online (Sandbox Code Playgroud)struct X { const static int …
Real World Haskell,第 4 章,第 98 页询问是否words
可以使用折叠来实现,这也是我的问题:
是否可以?如果不是,为什么?如果是,如何?
我想出了以下内容,这是基于这样的想法,即每个非空格都应该添加到输出列表中的最后一个单词之前(这发生在otherwise
守卫中),并且空格应该触发将一个空单词附加到如果还没有输出列表(这在if
- then
- 中处理else
)。
myWords :: String -> [String]
myWords = foldr step [[]]
where
step x yss@(y:ys)
| x == ' ' = if y == "" then yss else "":yss
| otherwise = (x:y):ys
Run Code Online (Sandbox Code Playgroud)
显然,这个解决方案是错误的,因为输入字符串中的前导空格会导致输出字符串列表中的一个前导空字符串。
在上面的链接中,我为其他读者研究了几个建议的解决方案,其中许多解决方案的工作方式与我的解决方案类似,但它们通常对折叠的输出进行“后处理”,例如,tail
如果有是一个空的前导字符串。
其他方法使用元组(实际上只是对),因此折叠处理对并且可以很好地处理前导/尾随空格。
在所有这些方法中,foldr
(或另一个折叠,fwiw)不是提供开箱即用的最终输出的函数;总是有其他东西必须以某种方式调整输出。
因此,我回到最初的问题并询问是否真的可以words
使用折叠来实现(以正确处理尾随/前导/重复空格的方式)。通过使用折叠,我的意思是折叠功能必须是最外层的功能:
myWords :: String -> [String]
myWords input = foldr step seed input
Run Code Online (Sandbox Code Playgroud) 这个问题不是主观的。参考书中使用了一个非常具体的动词,我想了解该措辞的含义,因为我担心我误解了一些东西。
从Learn You a Haskell 中,以下段落是包含“我们假设*
”的第三段也是最后一段。
Run Code Online (Sandbox Code Playgroud)data Barry t k p = Barry { yabba :: p, dabba :: t k }
现在我们想让它成为
Functor
.Functor
想要那种类型,* -> *
但Barry
看起来没有那种类型。什么样的Barry
?好吧,我们看到它需要三个类型参数,所以它将是something -> something -> something -> *
. 可以肯定地说,这p
是一个具体的类型,因此有一种*
. 对于k
,我们假设*
并且因此推而广之,t
有一种* -> *
。现在让something
我们用我们用作占位符的s替换这些种类,我们看到它有一种(* -> *) -> * -> * -> *
.
我们为什么要假设任何事情?在阅读“我们假设 X(即我们假设 X 为真)”时,我很自然地认为我们还应该考虑 X …
这是 3 种类型的多态函数:
:t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
Run Code Online (Sandbox Code Playgroud)
这里是一个非多态函数:
:t Data.Char.digitToInt
Data.Char.digitToInt :: Char -> Int
Run Code Online (Sandbox Code Playgroud)
如果我们将前者应用于后者,我们会得到一个多态的函数:1 类型:
:t (.) Data.Char.digitToInt
(.) Data.Char.digitToInt :: (a -> Char) -> a -> Int
Run Code Online (Sandbox Code Playgroud)
这意味着它(.)
是“实例化的”(我不确定这是正确的术语;作为 C++ 程序员,我会这样称呼它)b === Char
和c === Int
,因此(.)
被应用的的签名digitToInt
如下
(Char -> Int) -> (a -> Char) -> a -> Int
Run Code Online (Sandbox Code Playgroud)
我的问题是:有没有办法在屏幕上打印这个签名,给定(.)
,digitToInt
以及我想将前者应用于后者的“信息”?
对于谁感兴趣,这个问题早先作为这个问题的副本被关闭了。
haskell types type-systems functional-programming polymorphic-functions
我有这个玩具示例,
template <typename TChild>
struct Base {
template <typename T>
using Foo = typename TChild::template B<T>;
};
struct Child : Base<Child> {
template <typename T>
using B = T;
};
using Bar = Child::Foo<int>;
Run Code Online (Sandbox Code Playgroud)
无法编译。目的是我有一个父类,它提供基于子类成员的类型计算。子类是通过 CRTP 提供的。然而线
using Foo = typename TChild::template B<T>;
Run Code Online (Sandbox Code Playgroud)
无法编译:
<source>: In instantiation of 'struct Base<Child>':
<source>:16:16: required from here
<source>:13:11: error: invalid use of incomplete type 'struct Child'
13 | using Foo = typename TChild::template B<T>;
| ^~~
<source>:16:8: note: forward declaration of 'struct Child' …
Run Code Online (Sandbox Code Playgroud) 我从真实世界的 Haskell 中读到
它的操作如下:当一个
seq
表达式被求值时,它会强制求值它的第一个参数,然后返回它的第二个参数。它实际上对第一个参数没有任何作用:seq
仅作为强制评估该值的一种方式存在。
我在那里强调了then因为对我来说它意味着两件事发生的顺序。
从Hackage我读到
seq a b
如果a
是底部,则的值是底部,否则等于b
。换句话说,它将第一个参数评估a
为弱头部范式(WHNF)。seq 通常用于通过避免不必要的懒惰来提高性能。关于求值顺序的注意事项:表达式
seq a b
不保证a
会在 之前求值b
。by 给出的唯一保证seq
是两者a
和b
将在seq
返回值之前进行评估。特别是,这意味着b
可以在 之前进行评估a
。[…]
此外,如果我# Source
从那里点击链接,页面不存在,所以我看不到seq
.
这似乎与此答案下的评论一致:
[…]
seq
不能在普通的 Haskell 中定义
另一方面(或在同一方面,真的),另一条评论写道:
“真实”
seq
在 GHC.Prim 中定义为seq :: a -> b -> b; …
haskell functional-programming lazy-evaluation order-of-execution weak-head-normal-form
I don't understand the following behavior.
The following code, aimed at computing the factorial at compile time, doesn't even compile:
#include <iostream>
using namespace std;
template<int N>
int f() {
if (N == 1) return 1; // we exit the recursion at 1 instead of 0
return N*f<N-1>();
}
int main() {
cout << f<5>() << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
and throws the following error:
...$ g++ factorial.cpp && ./a.out
factorial.cpp: In instantiation of ‘int f() [with int N = …
Run Code Online (Sandbox Code Playgroud)