小编anj*_*ruu的帖子

测试Monadic代码

我正在通过Brent YorgeyHaskell课程学习Haskell .我刚刚到达monad部分,虽然我认为我(最后)对如何使用monad有一个很好的把握,但我不明白如何测试使用它们的代码.

本节的练习是编写一个(简化的)风险模拟,它需要大量使用Rand StdGenmonad.特别是,我们必须编写以下函数:

type Army = Int

data Battlefield = Battlefield { attackers :: Army, defenders :: Army }

battle :: Battlefield -> Rand StdGen Battlefield
Run Code Online (Sandbox Code Playgroud)

这需要一个初始的战场,并模拟这场战斗将如何进行.

我有一个实现,但我不明白如何测试它.我无法"获取" Rand StdGen Battlefield返回的内部值battle,因此我无法在GHCI解释器中打印出来,这就是我到目前为止测试代码的方式.我也无法弄清楚如何在Haskell主函数或其他东西中打印战斗结果.人们如何测试这些功能?

monads haskell

10
推荐指数
1
解决办法
226
查看次数

Parser(Haskell)更好的应用实例

我正在完成Brent Yorgey Haskell课程,而我在为Applicative定义一个好的实例时遇到了麻烦.解析器定义如下:

newtype Parser a = Parser { runParser :: String -> Maybe (a, String) }
Run Code Online (Sandbox Code Playgroud)

该函数接受一个字符串,解析一定量的输入,并返回一个Maybe元组,其中第一个值是解析器的类型,其余的是未解析的字符串剩余部分.例如,这是正整数的解析器:

posInt :: Parser Integer
posInt = Parser f
  where
    f xs
      | null ns   = Nothing
      | otherwise = Just (read ns, rest)
      where (ns, rest) = span isDigit xs
Run Code Online (Sandbox Code Playgroud)

赋值是为Parser创建Applicative实例.我们从一个Functor实例开始(我认为这是相对简单的):

first :: (a -> b) -> (a,c) -> (b,c)
first f (a, c) = (f a, c)

instance Functor Parser where
  fmap f p = Parser f' 
    where f' …
Run Code Online (Sandbox Code Playgroud)

haskell functor applicative

7
推荐指数
2
解决办法
748
查看次数

为结构的每个实例生成顺序ID

我正在写一个系统,我有一个Objects 的集合,每个Object都有一个唯一的整数ID.这是我在C++中如何做到这一点:

class Object {
public:
  Object(): id_(nextId_++) { }

private:
  int id_;
  static int nextId_;
}

int Object::nextId_ = 1;
Run Code Online (Sandbox Code Playgroud)

这显然不是thread_safe,但如果我想要它,我可以创建nextId_一个std::atomic_int,或者在nextId_++表达式周围包装一个互斥.

我怎么做(最好是安全的)Rust呢?没有静态struct成员,全局可变变量也不安全.我总是可以nextId进入new函数,但是这些对象将被分配到很多地方,我宁愿nextId不管这个数字和yon.思考?

rust

7
推荐指数
2
解决办法
850
查看次数

以下链式赋值是否会导致未定义的行为?

以下代码是否调用未定义的行为C

int a = 1, b = 2;
a = b = (a + 1);
Run Code Online (Sandbox Code Playgroud)

我知道以下内容调用UB:

a = b = a++;
Run Code Online (Sandbox Code Playgroud)

原因是它违反了标准中的以下条款:

在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算来修改一次.此外,只能访问先前值以确定要存储的值.

但是,第一个代码段不违反此条款.一位同事说这种说法a = b = a+1也可能意味着

a = a + 1;
b = a + 1;
Run Code Online (Sandbox Code Playgroud)

要么

b = a + 1;
a = b;
Run Code Online (Sandbox Code Playgroud)

我认为,由于"从右到左"的相关性=,它总是必须意味着a = (b = (a+1)),而不是

a = a + 1;
b = a + 1;
Run Code Online (Sandbox Code Playgroud)

不过,我并不积极.是UB吗?

c undefined-behavior

6
推荐指数
1
解决办法
212
查看次数

Rust中的线程安全可变非拥有指针?

我正在尝试并行化我的算法.这是我将如何用C++编写它的草图:

void thread_func(std::vector<int>& results, int threadid) {
   results[threadid] = threadid;
}

std::vector<int> foo() {
  std::vector<int> results(4);

  for(int i = 0; i < 4; i++)
  {
     spawn_thread(thread_func, results, i);
  }

  join_threads();

  return results;
}
Run Code Online (Sandbox Code Playgroud)

这里的要点是每个线程都有一个它不拥有的共享可变对象的引用.在Rust中,这似乎很难做到.我是否应该尝试将它拼凑在一起(我猜这里)Mutex,Cell或者&mut,我应该遵循更好的模式吗?

multithreading rust

6
推荐指数
1
解决办法
1299
查看次数

使用boost几何来检查两条线是否有交点

是否可以使用boost :: geometry来检查两个线段(每个由2D中的两个点给出)是否相互交叉?如果可能的话,boost :: geometry是否也允许检查特殊情况,例如在另一条线上只有一个点(数字),或两条线是否相等?

c++ geometry boost numerical-methods boost-geometry

5
推荐指数
1
解决办法
5750
查看次数

SIMD实现std :: nth_element

我有一个算法,运行在我的双核,3 GHz英特尔处理器平均250毫秒,我正在尝试优化它.目前,我有一个std::nth_element呼叫,std::vector在150到300个元素之间调用大约6000次,平均需要50ms.我花了一些时间来优化我使用的比较器,它目前double从向量中查找两个并执行简单的<比较.比较器运行的时间可以忽略不计std::nth_element.比较器的拷贝构造函数也很简单.

由于此调用当前占用了我的算法的20%的时间,并且由于时间大部分花费在nth_element我没写的代码上(即不是比较器),我想知道是否有人知道优化的方法nth_element使用SIMD或任何其他方法?我已经看到了一些关于std::nth_element使用OpenCL和多线程进行并行化的问题,但由于这些向量很短,我不确定从这种方法中获得多少好处,尽管我很容易被告知我错了.

如果有SSE方法,我可以使用任何SSE指令(当前,我认为)SSE4.2.

谢谢!

c++ performance sse simd stl-algorithm

5
推荐指数
1
解决办法
746
查看次数

可以将一个双精度结构转换为C中的双精度数组吗?

这在C中合法吗?

struct Doubles
{
  double a,b,c;
};

void foo(struct Doubles* bar)
{
  double* baz = (double*)bar;
  baz[0]++;
  baz[1]++;
  baz[2]++;
}
Run Code Online (Sandbox Code Playgroud)

我知道它在MSVC 2010上"有效",但我不知道它是否合法,或者不同的布局是否会导致UB.

c struct casting

4
推荐指数
1
解决办法
79
查看次数

划分单位球体

我想制作一个单位向量的查找表。每个单位向量将映射到该表中的一个容器,并且该容器将包含具有相似方向的一小组向量的一些信息。

我可以轻松地使用 ($\theta$, $\phi$, 1) 表示向量,然后将角度范围切入容器以制作 2D 查找表(因此第一个容器是 0 到 $2* 范围内的 theta \pi / N$,其中 N 是我想要的 theta 方向的 bin 数量)。这样做的问题是,我认为某些箱将比其他箱代表单位球体表面上更大的区域,并且我希望获得大致相同大小的区域。

我认为均匀划分角度范围会使某些垃圾箱比其他垃圾箱更大,这是错误的吗?如果没有,有人知道制作这个查找表的更好方法吗?

我发现了一些像这样的论文和演示文稿,但我不会撒谎,我不明白它(我听说过勒贝格测度,但如果我知道它意味着什么,我会被诅咒的),而且它无论如何,看起来并不是特别有希望。

geometry computational-geometry

4
推荐指数
1
解决办法
1479
查看次数

为自定义特征提供毯子特征实现

我采取的做法迅速几何箱子,我想实现两个结构,Vector以及Normal(这是因为标准的矢量和法向矢量地图通过一定的转换不同).我已经实现了以下特征:

trait Components {
  fn new(x: f32, y: f32, z: f32) -> Self;
  fn x(&self) -> f32;
  fn y(&self) -> f32;
  fn z(&self) -> f32;
}
Run Code Online (Sandbox Code Playgroud)

我也想将两个向量加在一起,以及两个法线,所以我有块看起来像这样:

impl Add<Vector> for Vector {
  type Output = Vector;
  fn add(self, rhs: Vector) -> Vector {
    Vector { vals: [
      self.x() + rhs.x(), 
      self.y() + rhs.y(), 
      self.z() + rhs.z()] }
  }
}
Run Code Online (Sandbox Code Playgroud)

impl对于Normals 几乎完全相同.我真正想要的是Add impl为每个实现的结构提供一个默认值Components,因为通常它们都将以相同的方式添加(例如,第三个被调用的结构Point将执行相同的操作).是否有这样做除了用于写出三个相同实现的方式Point,VectorNormal …

rust

4
推荐指数
1
解决办法
1688
查看次数

Rust中的Box <T>到&T

如果我有一个特征,我如何调用一个期望特征对象的函数Box<T>?换一种说法:

trait T { ... }

fn func(t: &T) { ... }

fn some_other_func() {
   b: Box<T>; // Provided

   // These work, but is there a better way?
   func( &*b );                // 1
   func( Borrow::borrow(&b) ); // 2
}
Run Code Online (Sandbox Code Playgroud)

1和2都错了.我错过了一些明显的东西吗

traits rust

3
推荐指数
1
解决办法
162
查看次数

Rust中的复制语义字面上会成为内存中的副本吗?

假设我在Rust中有以下结构:

struct Num {
  pub num: i32;
}

impl Num {
  pub fn new(x: i32) -> Num {
    Num { num: x }
  }
}

impl Clone for Num {
  fn clone(&self) -> Num {
    Num { num: self.num }
  }
}

impl Copy for Num { }

impl Add<Num> for Num {
  type Output = Num;
  fn add(self, rhs: Num) -> Num {
    Num { num: self.num + rhs.num }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后我有以下代码片段:

let a = Num::new(0);
let b …
Run Code Online (Sandbox Code Playgroud)

rust

2
推荐指数
2
解决办法
458
查看次数