I've been asking a few questions about strictness, but I think I've missed the mark before. Hopefully this is more precise. Lets say we have: n = 1000000 f z = foldl' ((x1, x2) y -> (x1 + y, y - x2)) z [1..n] Without changing f , what should I set z = ... So that fz does not overflow the stack? (ie runs in constant space regardless of the size of n) Its okay if the answer req
我一直在问严格的几个问题,但我认为我之前错过了这个标记。 希望这更准确。 可以说我们有: n = 1000000 f z = foldl' ((x1, x2) y -> (x1 + y, y - x2)) z [1..n] 不改变f ,我应该设置什么 z = ... 所以fz不会溢出堆栈? (即不管n的大小如何都在恒定的空间中运行) 它可以,如果答案需要GHC扩展。 我的第一个想法是定义: g (a1, a2) = (!a1, !a2) 接着 z = g (0, 0) 但我不认为g是有效的Haskell。 所
I am quite new to Haskell and I am wanting to create a histogram. I am using Data.Vector.Unboxed to fuse operations on the data; which is blazing fast (when compiled with -O -fllvm) and the bottleneck is my fold application; which aggregates the bucket counts. How can I make it faster? I read about trying to reduce the number of thunks by keeping things strict so I've made things strict
我对Haskell很新,我想创建一个直方图。 我正在使用Data.Vector.Unboxed来融合数据上的操作; 这是快速的(用-O -fllvm编译时),瓶颈是我的折叠应用程序; 它汇总了桶的数量。 我怎样才能让它更快? 我读过关于通过严格保密来减少Thunk的数量,所以我通过使用seq和foldr来制定严格的规定,但是没有看到性能提高。 强烈鼓励您的想法。 import qualified Data.Vector.Unboxed as V histogram :: [(Int,Int)] histogram = V.
We know that the $ operator binds the loosest, and also associates to the right, which means, [1..] should be evaluated first, and hence, shouldn't it run into an infinite loop? Why is it even stopping at all? The $ is a red herring here. take 2 $ [1..] is precisely identical to take 2 [1..] . The $ only affects what is an argument to what; it has no effect at all on when things get eva
我们知道$运算符绑定最松散的,也是右边的关联,这意味着应该先评估[1 ..],因此它不应该陷入无限循环? 为什么它甚至停下来呢? $是这里的一条红鲱鱼。 take 2 $ [1..]是完全相同的take 2 [1..] 。 $只影响什么是什么论点; 当事情得到评估时,它根本没有任何作用。 (例如: print 2 + 2 ==> (print 2) + 2 {- Doesn't work. -} print $ 2 + 2 ==> print (2 + 2) {- Works. -} 美元影响print是否
I've been reading this http://www.haskell.org/haskellwiki/Hask. I'm struggling with this part.. undef1 = undefined :: a -> b undef2 = _ -> undefined And why they behave like this.. seq undef1 () = undefined seq undef2 () = () undef2 () = undefined What is the reason for this? I would like to understand this behaviour but I don't even know where to begin. In particular, w
我一直在阅读这个http://www.haskell.org/haskellwiki/Hask。 我正在努力与这部分.. undef1 = undefined :: a -> b undef2 = _ -> undefined 为什么他们的行为像这样.. seq undef1 () = undefined seq undef2 () = () undef2 () = undefined 这是什么原因? 我想了解这种行为,但我甚至不知道从哪里开始。 特别是,为什么undef2在严格评估下表现不同? 特殊函数seq其第一个参数评估为弱头标准形式,然后返回其第
I'm trying to better understand Haskell's laziness, such as when it evaluates an argument to a function. From this source: But when a call to const is evaluated (that's the situation we are interested in, here, after all), its return value is evaluated too ... This is a good general principle: a function obviously is strict in its return value, because when a function application
我试图更好地理解Haskell的懒惰,比如何时评估一个函数的参数。 来自此源: 但是当对const一个调用进行评估时(这就是我们感兴趣的情况,毕竟在这里),它的返回值也被评估......这是一个很好的总体原则:一个函数显然是严格的返回值,因为当需要评估函数应用程序时,它需要在函数的主体中评估返回的内容。 从那里开始,您可以通过查看返回值总是取决于什么来了解必须评估的内容。 你的功能在这些论据中将是严格的,在其他
There are lots of good questions and answers about foldl , foldr , and foldl' in Haskell. So now I know that: 1) foldl is lazy 2) don't use foldl because it can blow up the stack 3) use foldl' instead because it is strict (ish) How foldl is evaluated: 1) a whole bunch of thunks are created 2) after Haskell is done creating thunks, the thunks are reduced 3) overflow the
在Haskell中有关于foldl , foldr和foldl'很多很好的问题和答案。 所以现在我知道: 1) foldl是懒惰的 2)不要使用foldl因为它会炸毁堆栈 3)用foldl'来代替,因为它是严格的(ish) 如何评估foldl : 1)创建了一大堆thunk 2)在Haskell创建thunk之后,thunk被减少 3)如果太多的thunk,堆溢出 我感到困惑的是: 1)为什么减少必须发生在所有thunk-ing之后? 2)为什么不foldl评估就像foldl'
I read that the $! operator forces strict evaluation. So why does this still work? Prelude> take 10 $! repeat 1 [1,1,1,1,1,1,1,1,1,1] I was expecting ghc to grind away forever trying to evaluate the infinite list of 1's. $! forces its second argument to weak head normal form, which basically means it evaluates its argument's outermost constructor. So in your case, it will not fo
我读过$! 运营商力量严格评估。 那么为什么这仍然有效? Prelude> take 10 $! repeat 1 [1,1,1,1,1,1,1,1,1,1] 我期待着ghc永远试图评估1的无限列表。 $! 强制它的第二个参数是弱头标准形式,这基本上意味着它评估它的参数的最外层构造函数。 所以在你的情况下,它不会强制整个列表的评估,但只评估最外层(即第一个) :构造函数。 Haskell对WHNF的正常形式有一个很好的解释:什么是弱头标准形式? 。 请注意,
I am relatively new to Haskell and I am trying to learn how different actions can be executed in sequence using the do notation. In particular, I am writing a program to benchmark an algorithm (a function) foo :: [String] -> [String] To this purpose I would like to write a function like import System.CPUTime benchmark :: [String] -> IO Integer benchmark inputList = do
我对Haskell相对比较陌生,我正试着学习如何使用符号按顺序执行不同的动作。 特别是,我正在编写一个程序来对一个算法(一个函数)进行基准测试, foo :: [String] -> [String] 为此我想写一个函数 import System.CPUTime benchmark :: [String] -> IO Integer benchmark inputList = do start <- getCPUTime let r = foo inputList e
I have been wondering about this a lot, but I haven't been able to find anything about it. When using the seq function, how does it then really work? Everywhere, it is just explained saying that seq ab evaluates a , discards the result and returns b . But what does that really mean? Would the following result in strict evaluation: foo s t = seq q (bar q t) where q = s*t What I m
我一直在想这很多,但我一直没有找到任何关于它的事情。 当使用seq功能时,它如何真正起作用? 在任何地方,只是解释说seq ab评估a ,丢弃结果并返回b 。 但是,这到底意味着什么? 以下将导致严格的评估: foo s t = seq q (bar q t) where q = s*t 我的意思是,在q严格在使用前评估bar ? 以下是否等同: foo s t = seq (s*t) (bar (s*t) t) 我觉得有点难以弄清这个功能的功能。 你不是一个人。 由于几个
This may now be a bit fuzzy, but I've been wondering that for a while. To my knowledge with ! , one can make sure a parameter for a data constructor is being evaluated before the value is constructed: data Foo = Bar !Int !Float I have often thought that laziness is a great thing. Now, when I go through sources, I see strict fields more often than the ! -less variant. What is the advan
这现在可能有点模糊,但我一直在想。 以我的知识! ,可以确保在构造值之前正在评估数据构造函数的参数: data Foo = Bar !Int !Float 我经常认为懒惰是件好事。 现在,当我通过消息来源时,我经常看到严格的领域比! 无变体。 这有什么好处,为什么我不应该保持懒惰? 除非在Int和Float字段中存储大量计算,否则大量的繁琐计算可能会在thunk中累积。 例如,如果您重复将1添加到数据类型的惰性Float字段中,它将占用越