我正在尝试编写一个能够有效地告诉我何时的函数 列表中的项目可以被一个范围内的所有项目整除或不整除。问题是,我不知道在遇到错误时立即停止列表理解。
allDivisByRng n start stop =
[n `mod` x == 0 | x <- [start, start+1 .. stop]]
我已经尝试takeWhile
但是无法做到我想做的事情。请指教。
allDivisByRng n start stop =
takeWhile( == True ) [ n `mod` x == 0 | x <- [start, start+1.. stop] ]
当我运行allDivisByRng 10 2 4
时,我会得到一个真实的列表
其他一些示例运行
*Main> allDivisByRng 12 2 10
[True,True,True]
*Main> allDivisByRng 12 2 150
[True,True,True]
-- I want this to return false
*Main> allDivisByRng 2520 2 10
[True,True,True,True,True,True,True,True,True]
-- I want this to return True
我也尝试过搜索False
allDivisByRng n start stop =
takeWhile( == False ) [ n `mod` x == 0 | x <- [start, start+1.. stop] ]
*Main> allDivisByRng 10 2 3
[]
-- want false to be returned
*Main> allDivisByRng 10 2 10
[]
-- want false to be returned
*Main> allDivisByRng 2520 2 10
[]
-- want true to be returned
*Main> allDivisByRng 12 2 10
[]
-- want false to be returned
答案 0 :(得分:5)
函数all
,
all :: Foldable t => (a -> Bool) -> t a -> Bool
允许您检查可折叠结构的所有元素是否满足特定条件。在你的情况下,
allDivisByRng n start stop = all ((== 0) . (mod n)) [start..stop]
答案 1 :(得分:2)
不需要&#34;停止列表理解&#34;在哈斯克尔。默认情况下,评估为lazy。这意味着在实际需要之前,值并未真正计算出来。
这使我们可以使用无限的数据结构:
take 10 [1..]
--> [1,2,3,4,5,6,7,8,9,10]
或者结构中包含无效值的结构:
take 1 ["It works!", error "Exception thrown"]
--> "It works!"
所以我们只需要将列表处理成一个函数,将布尔列表减少到一个bool。
Hoogle是一个很棒的小工具,用于搜索与给定类型签名匹配的函数。我建议你熟悉它,因为通常情况下,你并不能找到你正在寻找的东西。
在这种情况下,搜索[Bool] -> Bool
(将布尔值列表减少为单个布尔值的函数)为我们提供了Prelude中定义的以下函数(无需导入):
and :: Foldable t => t Bool -> Bool
看看你是否可以应用它来获得你想要的东西!
恰好有另一个函数对我们想要的东西有点闭合:测试列表中的所有元素是否满足谓词。有了这个&#34; all
&#34;功能,我们可以用非常清晰的方式重写你的功能(imo):
allDivisByRng n start stop =
all (n `isDividedBy`) [start .. stop]
where
n `isDividedBy` x = n `mod` x == 0