使用列表推导生成三元组:同区间取值能否简化写法?
更简洁的Haskell三元组生成方式
嘿,这个问题问得太到位了!当你需要生成所有元素都取自同一列表的多元组时,完全没必要重复写三次相同的生成器——Haskell给我们提供了更优雅的写法。
下面两种方法都能替代你原来的列表推导式,而且更简洁,扩展性也更强:
方法1:使用replicateM(最推荐)
如果你导入了Control.Monad模块,replicateM就是专门干这个的:它会重复执行n次同一个monadic操作(对于列表来说,就是从列表里选元素),并生成所有可能的组合结果。
对应你的需求,代码可以写成:
import Control.Monad (replicateM) result = replicateM 3 [1..3]
这行代码和你原来的[(a,b,c) | a <- [1..3], b <- [1..3], c <- [1..3]]完全等价,甚至当你需要生成四元组、五元组时,只需要把3改成对应的数字就行,比如replicateM 5 [1..3]就能生成所有5个元素都来自[1..3]的五元组,超级方便!
方法2:使用sequence + replicate
如果你不想额外导入模块,也可以用sequence结合replicate来实现:
result = sequence (replicate 3 [1..3])
replicate 3 [1..3]会生成一个包含三个[1..3]的列表,而sequence对于列表monad来说,会把这个列表展开成所有可能的元素组合,结果和上面的方法完全一致。
为什么这些方法等价?
在Haskell里,列表的monadic行为就是非确定性选择:每个<-在列表推导式里都是一次选择,而replicateM n xs本质上就是把这个选择重复n次,自动帮你生成所有可能的笛卡尔积——这正好就是你原来的列表推导式在做的事情。
内容的提问来源于stack exchange,提问作者Luca9984
相关产品推荐
相关产品推荐

