I have question about weak head normal form and normal form. Weak head normal form means, the expression will only evaluate as far as necessary to reach to a data constructor. Normal form means, the expression will be fully evaluated. Now, I have following expression: x -> x * 10 Why the expression above is in normal form? "Papu" ++ "chon" Why the expression above is in neither WHNF
我有疑问弱头正常形式和正常形式。 弱头正常形式意味着,表达式只会根据需要进行评估以达到数据构造函数。 正常形式意味着,表达式将被充分评估。 现在,我有以下表达方式: x -> x * 10 为什么上面的表达式是正常形式? "Papu" ++ "chon" 为什么上面的表达既不是WHNF也不是NF? WHNF的评估足以达到数据构造函数或lambda函数。 如果你有一个lambda函数没有被参数调用,那么无论如何你都无法对它进行评估。 所
As far as I know, seq ab evaluates (forces) a and b before returning b . It does not guarantee that a is evaluated first. pseq ab evaluates a first, then evaluates/returns b . Now consider the following: xseq a b = (seq a id) b Function application needs to evaluate the left operand first (to get a lambda form), and it can't blindly evaluate the right operand before entering the functi
据我所知, seq ab评估(力) a和b返回前b 。 它并不保证首先评估a 。 pseq ab计算a第一,然后评估/返回b 。 现在考虑以下几点: xseq a b = (seq a id) b 函数应用程序需要先评估左操作数(以获得lambda表单),并且它不能在进入函数之前盲目评估右操作数,因为这会违反Haskell的非严格语义。 因此(seq a id) b必须首先评估seq a id ,这会强制a和id (以某种未指定的顺序(但评估id不做任何事情)),然后返回id b (
The Haskell docs explain the evaluate function: Forces its argument to be evaluated to weak head normal form when the resultant IO action is executed. Prelude Control.Exception> let xs = [1..100] :: [Int] Prelude Control.Exception> :sprint xs xs = _ Prelude Control.Exception> let ys = evaluate xs Prelude Control.Excepti
Haskell文档解释了evaluate函数: 当生成的IO操作执行时,强制其参数被评估为弱头标准形式。 Prelude Control.Exception> let xs = [1..100] :: [Int] Prelude Control.Exception> :sprint xs xs = _ Prelude Control.Exception> let ys = evaluate xs Prelude Control.Exception> :t ys ys :: IO [Int] Prelude Control.Exception> ys [1,
I'm learning Haskell and currently trying to wrap my head around monads. While playing with some random number generation I got tripped on lazy evaluation once again. In an effort to simplify something close to the: roll :: State StdGen Int roll = do gen <- get let (n, newGen) = randomR (0,1) gen put newGen return n main = do gen <- getStdGen let x = sum $ ev
我正在学习Haskell,目前正试图将我的头围绕monad。 在玩一些随机数字时,我又一次怠惰评估。 为了简化以下几点: roll :: State StdGen Int roll = do gen <- get let (n, newGen) = randomR (0,1) gen put newGen return n main = do gen <- getStdGen let x = sum $ evalState (replicateM iterations roll) gen print x 变成这样的东西: roll' :: IO Int roll' = getStdRandom $ ra
Haskell has a magical function named seq , which takes an argument of any type and reduces it to Weak Head Normal Form (WHNF). I've read a couple of sources [not that I can remember who they were now...] which claim that "polymorphic seq is bad". In what way are they "bad"? Similarly, there is the rnf function, which reduces an argument to Normal Form (NF). But this
Haskell有一个名为seq的神奇函数,它接受任何类型的参数并将其减少为弱头范式(WHNF)。 我读过几个消息来源[我不记得他们现在是谁......],声称“多态seq不好”。 他们以什么方式“不好”? 类似地,还有rnf函数,它将参数减少到Normal Form(NF)。 但这是一种类方法; 它不适用于任意类型。 对我来说,似乎“显而易见”的是,人们可以改变语言规范,将其作为内置原语提供,类似于seq 。 据推测,这可能比只有seq更“糟糕”。
If want to pretend that Haskell is strict and I have an algorithm in mind that does not exploit laziness (so for instance it does not use infinite lists), what problems can occur if I used only strict data types and annotated any function that I use, to be strict in its arguments? Will there be a performance penalty, if so how bad; can worse problems occur? I know it is dirty, pointless and ug
如果想假装Haskell是严格的,并且我有一个不利用懒惰的算法(例如它不使用无限列表),如果我仅使用严格的数据类型并注释了我使用的任何函数,会发生什么问题,在其论据中要严格? 是否会有性能损失,如果有的话会有多糟糕; 会发生更糟的问题吗? 我知道这是肮脏,毫无意义和丑陋,无意识地使每个函数和数据类型严格,我不打算在实践中这样做,但我只想明白,如果这样做,Haskell默认情况下变得严格吗? 其次,如果我淡化偏
Why are there two different Writer-type monads in Haskell? Intuitively to me, reading "strict writer monad" means that the <> is strict, so that there's no thunk buildup in the log. However, looking at the source code, it turns out that that isn't the case: -- Lazy Writer instance (Monoid w, Monad m) => Monad (WriterT w m) where -- ... m >>= k = WriterT $ do
为什么Haskell中有两种不同的Writer类型monad? 直观地看,读“严格的作家monad”意味着<>严格,所以日志中没有thunk积累。 但是,从源代码看,情况并非如此: -- Lazy Writer instance (Monoid w, Monad m) => Monad (WriterT w m) where -- ... m >>= k = WriterT $ do ~(a, w) <- runWriterT m ~(b, w') <- runWriterT (k a) return (b, w <> w') 在严格的版本中,模式不是无可辩
I have a question concerning the definition of strict vs non-strict. The Haskell wiki-book for Laziness (http://en.wikibooks.org/wiki/Haskell/Laziness), under the section "Black-box strictness analysis", makes the following assertion: [Assuming a function f which takes a single parameter.] The function f is a strict function if, and only if, f undefined results in an error being prin
我有一个关于严格与非严格的定义的问题。 Haskell Laziness的wiki书(http://en.wikibooks.org/wiki/Haskell/Laziness)在“黑盒子严格性分析”一节的下面提出了以下断言: [假设函数f只有一个参数。]函数f是一个严格的函数,当且仅当f未定义时会导致错误被打印并暂停程序。 wiki将const与id对比,分别显示非严格和严格的函数。 我的问题是,我的印象是,foldl是以非严格的方式进行评估,造成不良的空间泄漏,而foldl'
We all know (or should know) that Haskell is lazy by default. Nothing is evaluated until it must be evaluated. So when must something be evaluated? There are points where Haskell must be strict. I call these "strictness points", although this particular term isn't as widespread as I had thought. According to me: Reduction (or evaluation) in Haskell only occurs at strictness p
我们都知道(或者应该知道)Haskell默认是懒惰的。 必须评估之前没有任何评估。 那么什么时候必须评估一下? 有些地方Haskell必须严格。 我称之为“严格点”,尽管这个特定术语并不像我想象的那样广泛。 据我说: Haskell中的减少(或评估)只发生在严格点上。 所以问题是: Haskell的严格性究竟是什么? 我的直觉表明, main seq / bang模式,模式匹配以及通过main执行的任何IO动作都是主要的严格点,但我不知道为什么
I understand (I think) that Haskell's seq , will (generally) reduce its first argument to WHNF, and see this behavior as expected in GHCi: λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in seq x 0 foo 0 However, though the documentation for evaluate says that it also reduces its argument to WHNF, it looks like it actually fully reduces its argument to normal form: λ> let x = (tra
我明白(我认为)Haskell的seq ,将(通常)减少它对WHNF的第一个参数,并在GHCi中看到预期的行为: λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in seq x 0 foo 0 然而,尽管evaluate文档说它也减少了对WHNF的争论,但它看起来实际上完全将它的论证缩减为正常形式: λ> let x = (trace "foo" Foo (trace "bar" Bar 100)) in evaluate x foo Foo bar (Bar 100) 我可以证实这一点(明显)与之不符 λ> let y