小编hkB*_*Bst的帖子

如何通过Haskell中的弱指针缓存构建一个具有重复消除的无限树

以下代码构建无限树,同时创建所有子树的缓存,以便不创建重复的子树.消除重复子树的基本原理来自对类似国际象棋游戏的状态树的应用:通过改变两个移动的顺序,人们通常可以最终处于相同的游戏状态.随着游戏的进行,无法访问的状态不应继续占用内存.我以为我可以通过使用弱指针来解决这个问题.不幸的是,使用弱指针将我们带入了IO Monad,这似乎已经破坏了足够/所有的懒惰,使得此代码不再终止.

因此我的问题是:是否有可能有效地生成一个没有重复子树的懒惰(游戏状态)树(并且没有泄漏内存)?

{-# LANGUAGE RecursiveDo #-}

import Prelude hiding (lookup)
import Data.Map.Lazy (Map, empty, lookup, insert)
import Data.List (transpose)

import Control.Monad.State.Lazy (StateT(..))
import System.Mem.Weak
import System.Environment

type TreeCache = Map Integer (Weak NTree)

data Tree a = Tree a [Tree a]
type Node = (Integer, [Integer])
type NTree = Tree Node

getNode (Tree a _) = a
getVals = snd . getNode

makeTree :: Integer -> IO NTree
makeTree n = fst <$> runStateT (makeCachedTree n) empty

makeCachedTree :: …
Run Code Online (Sandbox Code Playgroud)

tree haskell functional-programming weak-references infinite

9
推荐指数
1
解决办法
251
查看次数

使用最新的C++以类型安全的方式从枚举中随机选择一个元素

有没有办法以类型安全的方式从枚举中随机选择一个元素?

我能找到的最好的方法是引入一个终结符值作为枚举的最后一个元素,这样你知道有多少个值,然后生成一个随机整数,在你投射到枚举的适当范围内.但是终结符值并不代表任何内容,因此您的枚举值无效,而且这不是类型安全的.在最新的C++标准中有更好的方法吗?

c++ enums type-safety

8
推荐指数
1
解决办法
196
查看次数

Set类的位置在哪里?

在Haskell中Data.Set实现了一个具体的集合类型.普通[]列表还实现了一组(in Data.List)的所有操作.但似乎没有Set他们都实现的预定义类型类.你可以自己实现一个:

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies #-}

module Set where

import qualified Data.List as ConcreteList
import qualified Data.Set as ConcreteSet

class Set set a | set -> a where
  empty :: set
  singleton :: a -> set
  insert :: a -> set -> set
  delete :: a -> set -> set
  union :: set -> set -> set
  intersection :: set -> set -> set
  member :: a -> set -> Bool …
Run Code Online (Sandbox Code Playgroud)

haskell typeclass

5
推荐指数
3
解决办法
367
查看次数

C/C++负数的strtoul

以下C++程序调用strtoul为负1.由于在任何无符号类型中都没有可表示负数,我原以为这会失败并返回0(如果无法执行有效转换,则返回零值.),而是大返回正数(如果读取的值超出unsigned long int的可表示值范围,则函数返回ULONG_MAX(定义<climits>),并errno设置为ERANGE.).

#include <cstdlib>
#include <iostream>

int main () {
  {char s[] = "-1";
    for (int b=0; b<17; ++b)
      std::cout << "strtoul (unsigned) of " << s
                << " with base arg " << b
                << ": " << strtoul(s,0,b) << std::endl;}
}
Run Code Online (Sandbox Code Playgroud)

为什么strtoul没有失败并且为负数返回0?

c c++ string

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

是否可以使用记录语法声明约束数据类型?

是否可以使用记录语法声明约束数据类型?我的尝试

data ConstrainedRecord a where
  ConstrainedRecord :: Num a => { first :: a, second :: a }
Run Code Online (Sandbox Code Playgroud)

导致GHC抱怨"记录语法在这里是非法的".

syntax haskell gadt

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

为什么借用检查器不明白借用切片的不同部分从根本上是可以的?

split_at_mut函数(用于在索引处拆分可变切片)需要实现不安全的代码(根据 Rust 书)。但书中也说:“借用切片的不同部分从根本上是可以的,因为两个切片不重叠”。

我的问题:为什么借用检查器不明白借用切片的不同部分从根本上是可以的?(是否有原因阻止借用检查器理解此规则,或者只是由于某种原因尚未实施?)

使用 Rust 1.48 尝试建议的代码仍然会导致书中显示的错误:

fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) {
    let len = slice.len();

    assert!(mid <= len);

    (&mut slice[..mid], &mut slice[mid..])
}

fn main() {
    let mut vector = vec![1, 2, 3, 4, 5, 6];
    let (left, right) = split_at_mut(&mut vector, 3);
    println!("{:?}, {:?}", left, right);
}
Run Code Online (Sandbox Code Playgroud)

给出错误信息:

error[E0499]: cannot borrow `*slice` as mutable more than once at a time
 --> src/main.rs:6:30
  |
1 | …
Run Code Online (Sandbox Code Playgroud)

rust borrow-checker

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

`FromStr` 和 `TryFrom&lt;&amp;str&gt;` 之间有什么真正的区别吗?

FromStr和之间有什么真正的区别吗TryFrom<&str>

\n

从文档中的定义来看,一旦您替换 in ,它们看起来是&str相同TTryFrom

\n
pub trait FromStr {\n    type Err;\n    fn from_str(s: &str) -> Result<Self, Self::Err>;\n}\n\npub trait TryFrom<T> {\n    type Error;\n    fn try_from(value: T) -> Result<Self, Self::Error>;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然后是解析:

\n
\n

fromStr\xe2\x80\x99s from_str 方法经常被隐式使用,通过 str\xe2\x80\x99s\nparse 方法。

\n
\n

但是如果我们看看它的实现,我们会发现它除了提供稍微更短的调用方式之外没有做任何事情from_str

\n
pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {\n    FromStr::from_str(self)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如果您查看 TryFrom 的库实现,那么它几乎完全由数字转换组成,尽管也有:

\n
impl<\'_, T, const N: usize> TryFrom<&\'_ [T]> for [T; N] where\n    T: Copy, …
Run Code Online (Sandbox Code Playgroud)

rust

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

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

是否有一个标准的Haskell函数,比如迭代,什么都没有停止?

我想知道是否有一个标准函数迭代一个函数,该函数返回一个(Maybe值)超过一个初始值,收集列表中的值,但是当它到达Nothing时结束列表.这个功能可以像下面这样实现:

iterateMaybe f a = a : iterMaybe (f a) where
  iterMaybe Nothing = []
  iterMaybe (Just a) = a : iterMaybe (f a)
Run Code Online (Sandbox Code Playgroud)

或者略有不同:

iterateMaybe' f Nothing = []
iterateMaybe' f (Just a) = a : iterateMaybe' f (f a)
Run Code Online (Sandbox Code Playgroud)

Hoogle找不到匹配的任何功能.

haskell standard-library haskell-platform

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

在Haskell中展现这种类型的理由是什么?

文档中给出的示例unfoldr :: (b -> Maybe (a, b)) -> b -> [a]:

unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10
Run Code Online (Sandbox Code Playgroud)

可以使用冗余对轻松编写:

unfoldr (\b -> if b == 1 then Nothing else Just (b-1, b-1)) 11
Run Code Online (Sandbox Code Playgroud)

这对unfoldr需要什么(a,b)?为什么它的类型不是(a -> Maybe a) -> a -> [a]

haskell types unfold

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

如何在 Rust 中编写自己的交换函数?

std::mem::swap有签名:

pub fn swap<T>(x: &mut T, y: &mut T)
Run Code Online (Sandbox Code Playgroud)

如果我尝试实现它(游乐场):

pub fn swap<T>(x: &mut T, y: &mut T)
Run Code Online (Sandbox Code Playgroud)

我收到有关两个参数的生命周期的错误:

pub fn swap<T>(a: &mut T, b: &mut T) {
    let t = a;
    a = b;
    b = t;
}
Run Code Online (Sandbox Code Playgroud)

如果我将签名更改为:

error[E0623]: lifetime mismatch
 --> src/lib.rs:4:9
  |
1 | pub fn swap<T>(a: &mut T, b: &mut T) {
  |                   ------     ------
  |                   |
  |                   these two types are declared with different lifetimes...
...
4 |     b = t; …
Run Code Online (Sandbox Code Playgroud)

swap rust

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