我有一些不可复制的类型和一个消耗和(可能)生成它的函数:
type Foo = Vec<u8>;
fn quux(_: Foo) -> Option<Foo> {
Some(Vec::new())
}
Run Code Online (Sandbox Code Playgroud)
现在考虑一种在概念上非常类似的类型Box:
struct NotBox<T> {
contents: T
}
Run Code Online (Sandbox Code Playgroud)
我们可以编写一个临时移出内容的函数,NotBox并在返回之前放回一些东西:
fn bar(mut notbox: NotBox<Foo>) -> Option<NotBox<Foo>> {
let foo = notbox.contents; // now `notbox` is "empty"
match quux(foo) {
Some(new_foo) => {
notbox.contents = new_foo; // we put something back in
Some(notbox)
}
None => None
}
}
Run Code Online (Sandbox Code Playgroud)
我想编写一个与Boxes 一起使用的类似函数,但编译器不喜欢它:
fn baz(mut abox: Box<Foo>) -> Option<Box<Foo>> {
let foo = *abox; // now …Run Code Online (Sandbox Code Playgroud) 我对F#中的默认" = "(等于)运算符有疑问.它允许比较用户定义的联合类型.问题是:它的复杂性是什么?例如,让我们考虑以下类型:
type Tree<'a> =
| Nil
| Leaf of 'a
| Node of Tree<'a> * Tree<'a>
Run Code Online (Sandbox Code Playgroud)
以及树木:
let a : Tree<int> = Node (Node (Node (Leaf 1, Leaf 2), Node (Leaf 3, Node (Leaf 4, Leaf 5))), Node (Leaf 6, Nil))
let b : Tree<int> = Node (Node (Node (Leaf 1, Leaf 2), Node (Leaf 3, Node (Leaf 4, Leaf 5))), Node (Leaf 6, Nil))
let c : Tree<int> = Node (Node (Node (Leaf 1, Leaf 2), Nil), …Run Code Online (Sandbox Code Playgroud) complexity-theory f# equals user-defined-types operator-keyword
我想出的问题的最小例子如下:
struct __attribute__((aligned(16))) Foo {
float x, y, z;
Foo(float x, float y, float z) : x(x), y(y), z(z) {}
};
class Bar {
public:
Foo foo;
Bar(const Foo &foo) : foo(foo) {}
Foo bar() { return foo; }
};
int main()
{
Bar *bar = new Bar(Foo(0.0f, 0.0f, 0.0f));
bar->bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果使用clang++(版本3.4,Ubuntu 14.04中可用的默认版本)进行编译,这段代码会在运行时导致分段错误.使用g++(版本4.8.4)编译时不会发生此问题.这是编译器错误还是我的代码有问题?
作为旁注:如果bar是堆栈分配,程序不会崩溃,即:
Bar bar(Foo(0.0f, 0.0f, 0.0f));
bar.bar();
Run Code Online (Sandbox Code Playgroud)
按预期工作.
我注意到我有很多函数可以为我的值添加某种标签。例如,考虑这两种数据类型:
data Named a = Named String a
data Colored a = White a | Black a
Run Code Online (Sandbox Code Playgroud)
以及一些使用它们的函数:
name :: Foo -> Named Foo
color :: Named Foo -> Colored (Named Foo)
Run Code Online (Sandbox Code Playgroud)
在某些时候,我开始拥有带有许多类似嵌套“标签”的函数,所以我想知道是否可以将其概括为更易于管理。所有这些都可能很好地与 PureScript 的行多态性配合使用,但我们在这里谈论的是 Haskell。无论如何,这就是我想出的:
class Tag f where
separate :: f a -> (forall b. b -> f b, a)
Run Code Online (Sandbox Code Playgroud)
法律应该是这样的:
fx = let (f, x) = separate fx in f x
Run Code Online (Sandbox Code Playgroud)
或者不进行类型检查但更优雅的版本:
uncurry ($) . separate = id
Run Code Online (Sandbox Code Playgroud)
Tag也可以成为一个子类,Functor前提是
fmap g fx = let …Run Code Online (Sandbox Code Playgroud)