list monad 的魔力:
ghci> 让幂 (a, b) = [a ^ n | n 权力 (2, 3)
[1,2,4]
ghci> 地图权力 [(2, 3), (5, 3)]
[[1,2,4],[1,5,25]]
ghci> 排序
[[1,1],[1,5],[1,25],[2,1],[2,5],[2,25],[4,1],[4,5],[ 4,25]]
ghci> mapM 幂 [(2, 3), (5, 3)]
[[1,1],[1,5],[1,25],[2,1],[2,5],[2,25],[4,1],[4,5],[ 4,25]]
ghci> 映射产品它
[1,5,25,2,10,50,4,20,100]
ghci> let allPowers list = map product $ mapM powers list
ghci> allPowers [(2, 3), (5, 3)]
[1,5,25,2,10,50,4,20,100]
这可能值得更多解释。
你可以自己写
cartesianProduct :: [[a]] -> [[a]]
cartesianProduct [] = [[]]
cartesianProduct (list:lists)
= [ (x:xs) | x <- list, xs <- cartesianProduct lists ]
这样cartesianProduct [[1],[2,3],[4,5,6]] ⇒ [[1,2,4],[1,2,5],[1,2,6],[1,3,4],[1,3,5],[1,3,6]]。
但是,comprehensions 和 monads 故意相似。标准 Prelude 有 sequence :: Monad m => [m a] -> m [a],当 m 是列表单子 [] 时,它实际上完全按照我们上面写的。
作为另一个快捷方式,mapM :: Monad m => (a -> m b) -> [a] -> m [b] 只是sequence 和map 的组合。
对于每个碱基的不同幂的每个内部列表,您希望将它们乘以一个数字。你可以递归地写这个
product list = product' 1 list
where product' accum [] = accum
product' accum (x:xs)
= let accum' = accum * x
in accum' `seq` product' accum' xs
或使用折叠
import Data.List
product list = foldl' (*) 1 list
但实际上,product :: Num a => [a] -> a 已经定义了!我喜欢这种语言☺☺☺