tl; dr
不是 20< dr;长度$带10 $ nather
需要任何
成功地对列表进行修改(至少 []
或或(_:_:_)
)“缺乏”懒惰?
或者,换句话说,为什么不是(20>)。长度 。采用10 === const true
,以便将其应用于任何事物都不需要对该参数的评估?
是(20>)。长度 。服用10!== const true
必要吗?还是设计选择?无论哪种情况,为什么?
前言
这是最多我以前的问题。
我在那里问为什么 错误
prints ***异常:
反复,无限地。
答案令人满意。
但是,我的Lucubration
,我用 ghci
进行了一些播放,并意识到取0 $修复错误
预计会返回“”
和长度$ take 0 $修复错误
返回 0
。
另一方面,以下打印 ***异常:
无限流:
20 > (length $ take 10 $ fix error)
我知道 如果 甚至一个单个修复错误
是计算的(实际上是尝试的),结果就是结果,但我的问题是:为什么首先对它们进行的任何一个都需要评估,在该特定表达式?毕竟,长度$ the 10 $ nather
除了< = 10
,因此< 20
,因此表达式应评估为 true
。
实际上,我看到 20> (长度$ take 10 $ [fix error])
立即使用 true
返回。可能的重点是取10
期望在 [a]
上使用,因此长度$ take $ take 10 $ [fix error]
doens 't需要评估修复错误
以确保其在 [a]
上工作。确实,我已经验证了 20> (长度$ take 10 $ undefinited)
错误(即使没有无限重复错误),而 20> (长度$ take 10 $ [undefined])
true
返回。
也许那就是 willem van onSem在此评论中的意思。
无论如何,由于我可以写上述表达式,因为
((20 >) . length . take 10) $ fix error
我很想说
(20 >) . length . take 10 === const True
这是((20>)。长度。 true
就像 const true $ fix fix error
返回 true
。
但事实并非如此。为什么?
tl;dr
Isn't the fact that 20 < length $ take 10 $ whatever
requires whatever
to successfully pattern patch a list (at least either []
or (_:_)
) a "lack" of laziness?
Or, in other words, why isn't (20 >) . length . take 10 === const True
, so that applying either of them to anything requires no evaluation of the argument whatsoever?
Is (20 >) . length . take 10 !== const True
a necessity? Or a design choice? In either case, why?
Foreword
This is a follow up to my previous question.
There I asked about why fix error
prints *** Exception:
repeatedly and infinitely.
The answer was satisfactory.
My lucubration
However, I played around a bit with ghci
and realized that take 0 $ fix error
expectedly returns ""
, and length $ take 0 $ fix error
returns 0
.
On the other hand, the following prints the *** Exception:
infinite flow:
20 > (length $ take 10 $ fix error)
I understand that if even one single elmenent of fix error
is computed (attempted to, actually), the result is what it is, but my question is: why is the evaluation of any of them needed in the first place, in that specific expression? After all, length $ take 10 $ whatever
can't be other than <= 10
, hence < 20
, so the expression should evaluate to True
.
Actually, I see that 20 > (length $ take 10 $ [fix error])
returns immediately with True
. Probably the whole point is that take 10
expects to work on a [a]
, and so length $ take 10 $ [fix error]
doens't need to evaluate fix error
to be sure it's working on a [a]
. Indeed, I've verified that 20 > (length $ take 10 $ undefined)
errors too (even though not with an infinitely repeating error), whereas 20 > (length $ take 10 $ [undefined])
returns with True
.
Maybe that's what Willem Van Onsem meant in this comment.
Anyway, since I can write the expression above as
((20 >) . length . take 10) $ fix error
I would be tempted to say that
(20 >) . length . take 10 === const True
and hence I'd say it's reasonable for ((20 >) . length . take 10) $ fix error
to return True
just like const True $ fix error
returns True
.
But that's not the case. Why?
发布评论
评论(4)
取10
必须确定其参数是否为[]
或(:) value。const true
没有。长度
是严格的,因为它必须迭代其整个论点。构图并不意味着它只需要迭代足够的值才能获得足够大的数字以伪造(20&gt;)
。take 10
has to determine if its argument is a[]
or(:)
value.const True
does not.length
is strict, in that it has to iterate over its entire argument. Composition doesn't mean that it only has to iterate over enough values to get a number big enough to falsify(20 >)
.在Haskell中是不正确的。长度函数可能会在一般崩溃中或进入无限循环。在这两种情况下,它都不会给出有效的整数,并且缺乏有效整数不能与10进行比较。一般而言,评估任意表达式可能会导致一个值,例如(1 :: int)或 bottom 。底部概括了表达式可能不会导致值的所有原因。
表达式
。
20&lt;长度$ take 10 $无论如何
,因此必须对true
或底部进行评估,并且对于编译器false
甚至是一个选项。如您所见,true
和底部
是有效的结果。相比之下,与不同,因为它总是在true
中评估,而无需评估Is not correct in Haskell. The length function may in general crash or go into an infinite loop. In both cases it would not give a valid integer as result, and that lack of valid integer can not be compared to 10. In general, evaluating an arbitrary expression may result in either a value for example (1::Int) or bottom. Where bottom generalizes over all reasons why the expression may not result in a value.
The expression
20 < length $ take 10 $ whatever
, therefore must evaluate to eitherTrue
or bottom and for the compilerFalse
is even an option. As you have seen bothTrue
andbottom
are valid results. By contrast,const True whatever
is different as it always evaluates inTrue
without evaluatingwhatever
.如果需要,您可以定义一个“不安全”
拿走
的函数,该功能可以保证准确返回指定的元素数。dack 10未定义的
现在将是列表重复10个未定义的
,因此毫无困难地计算它少于20。回到您的问题,列表
the code
ting 10从任何意义上说,未定义的
没有长度,因此我们不能说它不到20个。即使使用懒惰的自然数也无济于事。现在,我们将拥有
长度(拿10)(():未定义)&gt; = 1 === true
,但我们仍然不能说它不到20,因为“它至少是一个”是有关该长度的所有信息。If you wanted, you could define an "unsafe"
take
-like function that is guaranteed to return exactly the specified number of elements.tack 10 undefined
will now be the listreplicate 10 undefined
, so there's no difficulty calculating that it's less than 20.Going back to your question, the list
take 10 undefined
has no length, in any sense, so we can't say it's less than 20. Even using lazy natural numbers won't help.Now we will have
length (take 10) (() : undefined) >= 1 === True
, but we still can't say it's less than 20, because "it's at least one" is all the information that exists about that length.您看到的行为与
长度
和&gt;
相比,与一起使用
更多。长度
必须返回特定的编号,(20&gt;)
只能在提供特定号码时运行。您认为管道中间正在处理什么数字?您确认
长度$ take 10 $修复错误
是(并且应该是)底部。列表修复错误
甚至没有一个单个元素可以在遇到错误之前对其进行查看,因此没有可以返回的数字可以准确地衡量列表的长度。 (可能会说它的长度可能为零,因为那里没有任何元素,但这意味着修复错误
等于[]
,它是ISN 'True。确实要求其长度是一个错误。 >。但是底部是可以互换的,因此这需要
20&gt;未定义的
也是true
。实际上,它需要(20&gt;)$ length $ take 50 $ fix fix error
to 也 be betrue
。您的直觉似乎是
长度。取10
无法返回大于10的值,因此(20&gt;)。长度 。服用10
应为const true
,因此不需要检查其输入。您显然注意到这对于当前的Haskell而言并不准确,但我认为这不是理想的行为。我的直觉是(20&gt;)
需要特定输入号,以返回true
;模糊的观念是,其输入不能是较大的数字不够好。如果其输入是错误(任何错误),则true
也不是false
是准确的返回值。请注意,
长度$ take 0 $ fix错误
是非常不同的情况。take
是等同于以下定义的:它检查要处理的元素的数量是否为零(或更少) 它检查了任何列表,如果这样返回特定的具体列表
[]
而无需检查输入列表(因此,fix>修复错误
或undefined
)。然后长度
可以测量[]
和返回 0 ,该小于20
。同样,
长度$ take 10 $ [fix error]
有效,因为取10
可以返回一个长度列表,而无需检查任何元素内部列表(因此而无需触发错误),长度
可以测量该列表并返回1
,该小于20
。这两种情况实际上都不需要任何未定义的属性的特定值,但是您的原始情况确实(错误的
length
)。这与“确保我们正在研究[a]
>”,而只是您的答案是否取决于未定义的值。The behaviour you're seeing is much more to do with
length
and>
than withtake
.length
has to return a specific number, and(20 >)
can only be run when supplied with a specific number. What number do you imagine is being processed in the middle of your pipeline?You acknowledge that
length $ take 10 $ fix error
is (and should be) bottom. There is not even one single element of the listfix error
that can be looked at before encountering an error so there is no number that could be returned that is an accurate measure of the list's length. (It might be tempting to say its length could be zero as there aren't any elements there, but that would imply thatfix error
is equal to[]
, which isn't true either. Really asking for its length is simply an error.)However, you now want to feed that bottom value into
(20 >)
and expect the resultTrue
. But bottoms are interchangeable, so this would require that20 > undefined
is alsoTrue
. And indeed, it would require(20 >) $ length $ take 50 $ fix error
to also beTrue
.Your intuition seems to be that
length . take 10
is not capable of returning a value greater than 10, so(20 >) . length . take 10
should beconst True
, and thus shouldn't need to examine its input. You've obviously noticed that that isn't accurate for current Haskell, but I don't think it would be desirable behaviour anyway. My intuition is that(20 >)
needs a specific input number that is less than 20 in order to returnTrue
; a vague notion that its input can't be a larger number isn't good enough. If its input is an error (any error) then neitherTrue
norFalse
is an accurate return value.Note that
length $ take 0 $ fix error
is a very different case.take
is defined equivalently to this:It checks whether the number of elements to be taken is zero (or less) before it examines any of the list, and if so it can return a specific concrete list
[]
without examining the input list (and therefore without triggering any errors fromfix error
orundefined
). Thenlength
can measure[]
and return0
, which is less than20
.Similarly,
length $ take 10 $ [fix error]
works becausetake 10
can return a list of length one without examining any of the elements inside the list (and thus without triggering the error), andlength
can measure that list and return1
, which is less than20
.Both of these cases never actually require a specific value for any property that is undefined, but your original case does (the
length
of an error). It's not to do with "ensuring we're working on[a]
", just whether your answer depends on a value that is undefined.