一个事务可以TVar
以原子方式更新两个不同的s吗?即,我可以从许多TVar
s 组成数据结构,以减少争用?如果是这样,你能提供一个例子吗?
在Haskell中有一个函数,比如说:
max_of_type :: (Num a) => a
Run Code Online (Sandbox Code Playgroud)
所以:
max_of_type :: Int == 2 ^ 31 - 1 // for example, implementation dependent
Run Code Online (Sandbox Code Playgroud) 可以说我有以下内容:
f (a, b) = if a == 0 then (0, 0) else (a * b, a / b)
x1 = make_strict (0, undefined)
x2 = (0, undefined)
g f :: (b -> b) -> a -> a
Run Code Online (Sandbox Code Playgroud)
如何定义make_strict
和g
:
g f x = ... f x ...
make_strict x = ...
Run Code Online (Sandbox Code Playgroud)
以便:
g f x1 == undef
g f x2 == (0, 0)
Run Code Online (Sandbox Code Playgroud)
基本上我想制作一对的严格版本然后我可以传递给一对函数,该函数需要一对,g
如果需要可能通过包装器.这里的具体实现f
只是一个例子,解决方案不应该依赖它.关键是我无法改变f
,我只能改变g
.
我一直在问一些关于严格性的问题,但我想我之前已经错过了这个标记.希望这更精确.
让我们说:
n = 1000000
f z = foldl' (\(x1, x2) y -> (x1 + y, y - x2)) z [1..n]
Run Code Online (Sandbox Code Playgroud)
不改变f
,我应该设置什么
z = ...
Run Code Online (Sandbox Code Playgroud)
那f z
不会溢出堆栈?(即无论n的大小如何,都在恒定的空间中运行)
如果答案需要GHC扩展,那也没关系.
我的第一个想法是定义:
g (a1, a2) = (!a1, !a2)
Run Code Online (Sandbox Code Playgroud)
然后
z = g (0, 0)
Run Code Online (Sandbox Code Playgroud)
但我认为g
Haskell无效.
根据我的理解,Foldable
基本上代表了具有许多可以迭代的相同类型的元素的结构,即列表,地图,集合等.
是否有类似Appendable
或Insertable
基本上代表可以添加元素的结构?当然,不能保证检索哪些元素的顺序.
如果已经有一个课,我宁愿不自己创建一个课程.
考虑以下功能:
import Data.List (find)
findInLists items = map $ find (`elem` items)
Run Code Online (Sandbox Code Playgroud)
可以这样调用,结果如下:
findInLists [2,3] [[1,2], [1,3,2], [4, -2, 8]] -> [Just 2, Just 3, Nothing]
Run Code Online (Sandbox Code Playgroud)
可以假设第一个参数已排序,但第二个参数不会排序.
如果n
是要搜索的所有列表中的项目总数(在这种特殊情况下,7,因为搜索在找到项目时停止)并且k
是要搜索的项目数,我相信此函数的运行时将是O(n * k)
.但是,这对于较大的k
时候n
也是不好的.
O(n * log k) + O(k * log k)
如果可能的话,我希望运行时更好或更好.最好的方法是什么?
我正在考虑Haskell中的列表,我想在其他语言中,一个人不会使用列表.当然,如果你以后需要这些值,你可能想要存储一个列表,但是如果它只是一个关闭,比如迭代[1..n]
,为什么要使用一个列表,其中所有真正需要的是一个递增的变量?
我还读到了"列表融合",并指出虽然Haskell编译器尝试实现此优化以消除中间列表,但它们通常不成功,导致垃圾收集器必须清理仅使用一次的列表.
此外,如果您不小心,可以轻松共享列表,这意味着垃圾收集器不会清理它,这可能导致内存耗尽,而算法以前设计为在恒定空间中运行.
所以我认为最好完全避免列表,至少当一个人实际上并不想"存储"列表时.
然后我遇到了conduit
,它说它是:
流数据问题的解决方案,允许在恒定存储器中生成,转换和消耗数据流.
这听起来很完美.我知道conduit
是针对IO
资源获取和发布问题而设计的,但是可以只将它用作替换列表吗?
例如,我可以执行以下操作:
fold f3 $ take 10 $ map f2 $ unfold f1 init_value
Run Code Online (Sandbox Code Playgroud)
并且通过一些适当放置的类型注释,使用整个过程的管道而不是列表?
我希望也许classy-prelude
允许这样的代码,但我不确定.如果有可能,有人可以举个例子吗,就像上面说的那样?
按照问题.我知道有一个"0但是真的"在布尔上下文中是真的但是否则为false,但是在布尔上下文中可以返回false但是具有非零值(显而易见的地方是返回状态,其中0表示成功,任何事情别的是错误).