标签: thunk

什么是'thunk'?

我已经看到它用于编程(特别是在C++领域)并且不知道它是什么.据推测它是一种设计模式,但我可能是错的.谁能举出一个很好的例子?

c++ thunk

123
推荐指数
8
解决办法
3万
查看次数

GHC的暴力有多原子?

GHC如何处理多个线程(显式线程或评估spark的内部线程)访问的thunk?是否会发生多个线程评估同一个thunk,重复工作?或者,如果thunks同步,如何,这样性能不会受到影响?

multithreading haskell lazy-evaluation ghc thunk

48
推荐指数
3
解决办法
2669
查看次数

当GHCi允许绑定时,了解thunk的不同行为

我一直在玩Simon Marlow关于Haskell中的并行和并发编程的书中的一些例子,偶然发现了一个我不太了解的有趣行为.这真的是我试图了解GHC的一些内部运作方式.

假设我在REPL中执行以下操作:

?» let x = 1 + 2 :: Int
?» let z = (x,x)
?» :sprint x
x = _
?» :sprint z
z = (_,_)
?» seq x ()
()
?» :sprint z
z = (3,3)
Run Code Online (Sandbox Code Playgroud)

好吧,这几乎是我的预期,除了z已经被评估为WHNF.让我们编写一个类似的程序并将其放在一个文件中:

module Thunk where

import Debug.Trace

x :: Int
x = trace "add" $ 1 + 2

z :: (Int,Int)
z = (x,x)
Run Code Online (Sandbox Code Playgroud)

在GHCi中摆弄它:

?» :sprint x
x = _
?» :sprint z
z = _
?» seq x () …
Run Code Online (Sandbox Code Playgroud)

haskell lazy-evaluation ghci thunk weak-head-normal-form

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

Haskell中的所有内容都存储在thunk中,即使是简单的值吗?

Haskell堆中以下值/表达式/函数的thunk是什么样的?

val = 5                -- is `val` a pointer to a box containing 5?
add x y = x + y        
result = add 2 val     
main = print $ result
Run Code Online (Sandbox Code Playgroud)

考虑到它的惰性评估模式,可以很好地了解这些在Haskell中的表示方式.

haskell lazy-evaluation thunk

41
推荐指数
4
解决办法
2923
查看次数

thunk使用了多少内存?

假设我有一个非常大的数字(数百万/十亿+)这些简单的Foo数据结构:

data Foo = Foo
    { a :: {-# UNPACK #-}!Int
    , b :: Int
    }
Run Code Online (Sandbox Code Playgroud)

随着这么多的浮动,有必要考虑他们消耗多少内存.

在64位机器上,每个Int都是8个字节,因此a只需要8个字节(因为它是严格的和解压缩的).但是会b占用多少内存?我想这会根据thunk是否被评估而改变,对吧?

我想在一般情况下这是不可能的,因为b可能依赖于任何数量的内存位置,只有在b需要评估的情况下才会留在内存中.但是,如果b只依赖(一些非常昂贵的操作)a呢?那么,是否有一种确定性的方式来判断将使用多少内存?

haskell lazy-evaluation thunk

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

thunk,期货和承诺有什么区别?

有关于它们的维基文章:(http://en.wikipedia.org/wiki/Futures_and_promises,http://en.wikipedia.org/wiki/Thunk_ ( delayed_computation)).但我不确定三者作为编程语言概念之间的确切差异是什么?期货和承诺只适用于并发编程吗?

future delayed-execution thunk promise

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

测试值是否已评估为弱头正常形式

在Haskell中,是否可以测试一个值是否已被评估为弱头正常形式?如果一个函数已经存在,我希望它有一个像这样的签名

evaluated :: a -> IO Bool
Run Code Online (Sandbox Code Playgroud)

有一些类似功能的地方.

一个以前的答案给我介绍:sprintghci的命令,该命令将打印已经被迫弱头部正常形态的值只有部分.:sprint可以观察是否已评估某个值:

> let l = ['a'..]
> :sprint l
l = _
> head l
'a'
> :sprint l
l = 'a' : _
Run Code Online (Sandbox Code Playgroud)

有可能IO检查本来是禁止的属性.例如,可以比较IO以查看两个值是否来自同一声明.这是由StableNames in提供System.Mem.StableName并用于解决数据统一中的可观察共享问题.相关内容StablePtr未提供检查引用值是否为弱头正常形式的机制.

haskell lazy-evaluation thunk weak-head-normal-form

17
推荐指数
3
解决办法
937
查看次数

如果thunk导致异常,那么异常是否仍然是thunk的结果?

我创建了这个小程序,它创建了一个长时间运行的thunk,最终因异常而失败.然后,多个线程尝试评估它.

import Control.Monad
import Control.Concurrent
import Control.Concurrent.MVar

main = do
    let thunk = let p = product [1..10^4]
                 in if p `mod` 2 == 0 then error "exception"
                                      else ()
    children <- replicateM 2000 (myForkIO (print thunk))
    mapM_ takeMVar children

-- | Spawn a thread and return a MVar which can be used to wait for it.
myForkIO :: IO () -> IO (MVar ())
myForkIO io = do
     mvar <- newEmptyMVar
     forkFinally io (\_ -> putMVar mvar ())
     return …
Run Code Online (Sandbox Code Playgroud)

haskell exception lazy-evaluation thunk

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

:sprint的多态值?

我想知道为什么在这种情况下的:sprint报告xs = _:

Prelude> xs = map (+1) [1..10]
Prelude> length xs
10
Prelude> :sprint xs
xs = _
Run Code Online (Sandbox Code Playgroud)

但在这种情况下不是:

Prelude> xs = map (+1) [1..10] :: [Int]
Prelude> length xs
10
Prelude> :sprint xs
xs = [_,_,_,_,_,_,_,_,_,_]
Run Code Online (Sandbox Code Playgroud)

注:我正在ghci-XNoMonomorphismRestriction.是否与xs第一种情况下的多态性类型有关,而在第二种情况下不是多态性的事实?我想知道内部发生了什么.

haskell ghci thunk monomorphism-restriction

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

Haskell Fibonacci解释

我对Haskell很陌生,我试图围绕Fibonacci序列的懒惰表达如何工作.

我知道之前已经问过这个问题,但是没有一个答案解决了我在查看结果时遇到的问题.

代码是使用的规范 zipWith

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Run Code Online (Sandbox Code Playgroud)

我理解以下内容:

  1. zipWith 字面上将两个列表拉到一起
  2. tail 抓取除列表的第一个元素之外的所有元素
  3. Haskell将'to-be'计算数据引用为thunks.

从我的理解,它首先添加[0,1,<thunk>][1,<thunk>]使用zipWith (+)给予[1,<thunk>].所以现在你有

fibs = 0 : 1 : 1 : zipWith (+) fibs (tail fibs)
Run Code Online (Sandbox Code Playgroud)

我用谷歌搜索过的很多参考文献都开始将上面的线"可视化"为

fibs = 0 : 1 : 1 : zipWith (+) [1,1,<thunk>] ([1,<thunk>]).
Run Code Online (Sandbox Code Playgroud)

我的问题是:

为什么 fibs 上面一行中 组件只对应[1,1,<thunk>] 而不是 [0,1,1,<thunk>]

不应该fibs包含整个列表加<thunk>

haskell functional-programming fibonacci lazy-evaluation thunk

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