让我们说我们有这种类型的声明:
data D a = A a | B a | C a | D a | E a | F a
Run Code Online (Sandbox Code Playgroud)
并希望在其上定义一个函数,该函数将数据构造函数分为两组.写这样的东西会很好:
g x | x `is` [A,B,C] = 1
| x `is` [D,E,F] = 2
Run Code Online (Sandbox Code Playgroud)
而不是分别在每个构造函数上匹配.
有没有办法实现这个目标?我看着uniplate,却找不到办法.
今天我正在编写Erlang编程书中的线程环练习,并搜索其他解决方案进行比较.我发现语言枪战与基准测试有着完全相同的问题.我的印象是,这是一个Erlang应该很快的领域,但事实证明C和C++再次位居榜首.我怀疑C/C++程序没有遵循"将令牌从线程传递给线程"的规则.在阅读它们之后,似乎它们都操纵了一些与Erlang代码不同的共享内存和全局变量,但我可能错了.
我的问题是:他们是在做同样的事情还是C/C++代码在概念上与Erlang代码不同(并且速度更快)?
还有一个问题:当解决方案非常相似时,为什么Haskell比Erlang更快?
我的理解是Int值是指向thunk(双重间接)的指针,而未装箱的Int#只是指向32/64位int的指针.那是对的吗?指针如何编码它指的是未装箱的值?
所述的Haskell标准规定,一个Int是"A固定精度整数类型至少与所述范围[-2 ^ 29 .. 2 ^ 29-1]".在GHC中是否有一些优化,其中那些额外的位用于消除间接?
如何在不经过Haskell的情况下使用异常IO
?
我有以下代码,用于在二元搜索树中插入元素,只需最少的比较,当元素是树的成员时不复制.我注意到,either
作为catch
和Left
作为throw
:
insert x t = either (const t) id (insert' x t Nothing)
where
insert' x E m = maybe (Right (T E x E)) (\v -> if x==v then Left E else Right (T E x E)) m
insert' x t@(T l v r) m = if x<v
then fmap (\l' -> T l' v r) (insert' x l Nothing)
else fmap (\r' -> T l v r') …
Run Code Online (Sandbox Code Playgroud) haskell-src-exts包具有很好的打印Haskell AST的功能.我想要做的是改变它在某些构造函数上的行为,在我的例子中是打印SCC编译指示的方式.因此,其他所有内容都应以默认方式打印,只有SCC的处理方式不同.是否可以在不复制源文件和编辑它的情况下完成,这就是我现在正在做的事情?
我在javascript中做了很多
some_var || some_var = function(){ return "blah"}();
Run Code Online (Sandbox Code Playgroud)
我想知道红宝石中的等价物是什么,所以我能做到
some_var ||= # sequence of operations
Run Code Online (Sandbox Code Playgroud)
编辑
这Proc.new.call
引起了我的注意,但我也是在某人的代码中遇到过这个:
a ||= begin
# do some stuff
# return some stuff
end
Run Code Online (Sandbox Code Playgroud)
这在功能上等同于使用Proc.new.call
??
edit2 人们似乎对我想要实现的目标感到困惑.想象一下这在javascript中:
function someExpensiveFunction(){
# do some really expensive stuff
return "some expensive calculations"
}
a || a = someExpensiveFunction();
Run Code Online (Sandbox Code Playgroud)
显然设置a
一次......一次调用昂贵的函数...在这种情况下我不关心范围,我只需要我的返回值是一个计算的事件序列而不是单个值.
我很确定我上面的例子a ||= begin; ... end;
是等价的......
我已经看到了这个权利的几个地方,包括SO:/sf/answers/1432722021/,/sf/answers/308027261/。我明白修改数据不需要锁,但在并发修改后最终会得到它的多个版本。这在实践中似乎不是很有用。我试图用下面的简单场景来描述这一点:
假设我们有 2 个线程 A 和 B。它们都在修改纯函数字典 D。此时它们不需要锁,因为数据是不可变的,因此它们输出新的字典 DA 和 DB。现在我的问题是如何协调 DA 和 DB,以便以后的操作可以看到数据的单一视图?
编辑:答案建议merge
在 DA 和 DB上使用函数。我看不出这是如何解决问题的,因为可能有另一个线程 C 与合并操作同时运行。声称纯函数式数据结构是无锁的,但使用合并函数听起来更像是最终一致性,这是另一回事。
multithreading haskell functional-programming data-structures
解决这个问题的方法是从一个衬套到一个衬套?是:
cat header main | tee main > /dev/null
Run Code Online (Sandbox Code Playgroud)
正如一些评论所注意到的,这不适用于大文件。
这是一个可行的示例:
$ echo '1' > h
$ echo '2' > t
$ cat h t | tee t > /dev/null
$ cat t
1
2
Run Code Online (Sandbox Code Playgroud)
并在哪里中断:
$ head -1000 /dev/urandom > h
$ head -1000 /dev/urandom > t
$ cat h t | tee t > /dev/null
^C
Run Code Online (Sandbox Code Playgroud)
该命令挂起,并在杀死它后留下:
$ wc -l t
7470174 t
Run Code Online (Sandbox Code Playgroud)
是什么导致命令卡住并无限增加行的上述行为?1行文件方案有什么不同?
我正在努力掌握do notation
Haskell 中的内容。
我可以将它与 Maybe 一起使用,然后打印结果。像这样:
maybeAdd :: Maybe Integer
maybeAdd = do one <- maybe1
two <- maybe2
three <- maybe3
return (one + two + three)
main :: IO ()
main = putStr (show $ fromMaybe 0 maybeAdd)
Run Code Online (Sandbox Code Playgroud)
但是,我没有使用单独的函数,而是尝试在主函数中使用带有 Maybe 的 do 表示法。但我没有任何运气。我尝试的各种尝试包括:
main :: IO ()
main = do one <- maybe1
two <- maybe2
three <- maybe3
putStr (show $ fromMaybe 0 $ return (one + two + three))
Run Code Online (Sandbox Code Playgroud)
main :: IO ()
main …
Run Code Online (Sandbox Code Playgroud) haskell ×7
monads ×2
android ×1
bash ×1
c ×1
c++ ×1
concurrency ×1
do-notation ×1
erlang ×1
exception ×1
ghc ×1
javascript ×1
linux ×1
pretty-print ×1
ruby ×1
shell ×1
unix ×1