列表理解的奇怪行为
Strange behaviour of list comprehensions
我正在学习 Haskell 的基础知识并尝试解决 Euler 项目的简单任务:找到 3 位数字 (100.999) 的最大回文。我写了这段代码:
palindrome = maximum $ filter (\a -> reverse a == a) $
map show [ x*y :: Int | x <- [100 .. 999],
y <- [x, x+1 .. 999]]
它给出了一个错误的答案 = 99999,当我将其更改为 x <- [307 .. 999]
答案仍然是错误的:94249(所有回文,但不是最大的)最后当我将其更改为 x <- [308 .. 999],
它给了我正确答案:906609。
我真的不明白这种行为:似乎在生成的列表中发生了某种溢出和截断。有人可以向我解释这种错误行为吗?我 不想 你回答这个任务:我知道我的解决方案不是很有效。我只想让您解释此代码行为(列表截断或内存问题)。谢谢
filter
的结果是 String
值的列表,因此 maximum
是按字典顺序比较它们。您需要先将值转换回 Int
s。类型签名确保 read
returns 值的正确类型。
palindrome :: Int
palindrome = maximum . map read . filter ...
另一种方法是仅在过滤器本身中将值转换为 String
:
palindrome :: Int
palindrome = maximum $ filter (\a -> let sa = show a in reverse sa == sa) [ x*y | x <- [100..999], y <- [x..999]]
我正在学习 Haskell 的基础知识并尝试解决 Euler 项目的简单任务:找到 3 位数字 (100.999) 的最大回文。我写了这段代码:
palindrome = maximum $ filter (\a -> reverse a == a) $
map show [ x*y :: Int | x <- [100 .. 999],
y <- [x, x+1 .. 999]]
它给出了一个错误的答案 = 99999,当我将其更改为 x <- [307 .. 999]
答案仍然是错误的:94249(所有回文,但不是最大的)最后当我将其更改为 x <- [308 .. 999],
它给了我正确答案:906609。
我真的不明白这种行为:似乎在生成的列表中发生了某种溢出和截断。有人可以向我解释这种错误行为吗?我 不想 你回答这个任务:我知道我的解决方案不是很有效。我只想让您解释此代码行为(列表截断或内存问题)。谢谢
filter
的结果是 String
值的列表,因此 maximum
是按字典顺序比较它们。您需要先将值转换回 Int
s。类型签名确保 read
returns 值的正确类型。
palindrome :: Int
palindrome = maximum . map read . filter ...
另一种方法是仅在过滤器本身中将值转换为 String
:
palindrome :: Int
palindrome = maximum $ filter (\a -> let sa = show a in reverse sa == sa) [ x*y | x <- [100..999], y <- [x..999]]