为什么是(20>)。长度 。取10 === const true

发布于 2025-01-26 22:27:47 字数 2355 浏览 3 评论 0 原文

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别低头,皇冠会掉 2025-02-02 22:27:48

取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 >).

っ〆星空下的拥抱 2025-02-02 22:27:48

毕竟,长度$拿10 $除了&lt; = 10 [...]

在Haskell中是不正确的。长度函数可能会在一般崩溃中或进入无限循环。在这两种情况下,它都不会给出有效的整数,并且缺乏有效整数不能与10进行比较。一般而言,评估任意表达式可能会导致一个值,例如(1 :: int)或 bottom 。底部概括了表达式可能不会导致值的所有原因。

表达式 20&lt;长度$ take 10 $无论如何,因此必须对 true 或底部进行评估,并且对于编译器 false 甚至是一个选项。如您所见, true 底部是有效的结果。相比之下,与不同,因为它总是在 true 中评估,而无需评估

After all, length $ take 10 $ whatever can't be other than <= 10 [...]

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 either True or bottom and for the compiler False is even an option. As you have seen both True and bottom are valid results. By contrast, const True whatever is different as it always evaluates in True without evaluating whatever.

苏大泽ㄣ 2025-02-02 22:27:48

如果需要,您可以定义一个“不安全” 拿走的函数,该功能可以保证准确返回指定的元素数。

tack :: Natural -> [a] -> [a]
tack 0 _ = []
tack n ~(x:xs) = x : tack (n-1) xs
-- Alternatively,
tack n xs = head xs : tack (n-1) (tail xs)

dack 10未定义的现在将是列表重复10个未定义的,因此毫无困难地计算它少于20。

回到您的问题,列表 the code ting 10从任何意义上说,未定义的 没有长度,因此我们不能说它不到20个。即使使用懒惰的自然数也无济于事。

data Nat = Z | S Nat deriving (Eq, Ord)
instance Num Nat where
  fromInteger 0 = Z
  fromInteger n = S (fromInteger (n - 1))
  ...

length :: [a] -> Nat
length = foldr S Z

take :: Nat -> [a] -> [a]
take (S n) (x : xs) = x : take n xs
take _ _ = []

现在,我们将拥有长度(拿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 :: Natural -> [a] -> [a]
tack 0 _ = []
tack n ~(x:xs) = x : tack (n-1) xs
-- Alternatively,
tack n xs = head xs : tack (n-1) (tail xs)

tack 10 undefined will now be the list replicate 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.

data Nat = Z | S Nat deriving (Eq, Ord)
instance Num Nat where
  fromInteger 0 = Z
  fromInteger n = S (fromInteger (n - 1))
  ...

length :: [a] -> Nat
length = foldr S Z

take :: Nat -> [a] -> [a]
take (S n) (x : xs) = x : take n xs
take _ _ = []

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.

寄居人 2025-02-02 22:27:48

您看到的行为与长度&gt; 相比,与 一起使用更多。 长度必须返回特定的编号,(20&gt;)只能在提供特定号码时运行。您认为管道中间正在处理什么数字?

您确认长度$ take 10 $修复错误是(并且应该是)底部。列表修复错误甚至没有一个单个元素可以在遇到错误之前对其进行查看,因此没有可以返回的数字可以准确地衡量列表的长度。 (可能会说它的长度可能为零,因为那里没有任何元素,但这意味着修复错误等于 [] ,它是ISN 'True。确实要求其长度是一个错误

。 >。但是底部是可以互换的,因此这需要 20&gt;未定义的也是 true 。实际上,它需要(20&gt;)$ length $ take 50 $ fix fix error to be be true

您的直觉似乎是长度。取10 无法返回大于10的值,因此(20&gt;)。长度 。服用10 应为 const true ,因此不需要检查其输入。您显然注意到这对于当前的Haskell而言并不准确,但我认为这不是理想的行为。我的直觉是(20&gt;)需要特定输入号,以返回 true ;模糊的观念是,其输入不能是较大的数字不够好。如果其输入是错误(任何错误),则 true 也不是 false 是准确的返回值。

请注意,长度$ take 0 $ fix错误是非常不同的情况。 take 是等同于以下定义的:

take n _
  | n <= 0  = []
take _ [] = []
take n (x:xs) = x : take (n - 1) xs

它检查要处理的元素的数量是否为零(或更少) 它检查了任何列表,如果这样返回特定的具体列表 [] 而无需检查输入列表(因此, 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 with take. 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 list fix 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 that fix 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 result True. But bottoms are interchangeable, so this would require that 20 > undefined is also True. And indeed, it would require (20 >) $ length $ take 50 $ fix error to also be True.

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 be const 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 return True; 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 neither True nor False is an accurate return value.

Note that length $ take 0 $ fix error is a very different case. take is defined equivalently to this:

take n _
  | n <= 0  = []
take _ [] = []
take n (x:xs) = x : take (n - 1) xs

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 from fix error or undefined). Then length can measure [] and return 0, which is less than 20.

Similarly, length $ take 10 $ [fix error] works because take 10 can return a list of length one without examining any of the elements inside the list (and thus without triggering the error), and length can measure that list and return 1, which is less than 20.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文