[英]Dynamically build list comprehension in Haskell
I am curious if it is possible to dynamically build a list comprehension in Haskell. 我很好奇是否有可能在Haskell中动态构建列表理解。
As an example, if I have the following: 举个例子,如果我有以下内容:
all_pows (a,a') (b,b') = [ a^y * b^z | y <- take a' [0..], z <- take b' [0..] ]
I get what I am after 我得到了我想要的东西
*Main> List.sort $ all_pows (2,3) (5,3)
[1,2,4,5,10,20,25,50,100]
However, what I'd really like is to have something like 但是,我真正喜欢的是拥有类似的东西
all_pows [(Int,Int)] -> [Integer]
So that I can support N
pairs of arguments without building N
versions of all_pows
. 因此,我可以支持
N
对参数,而无需构建N
版本的all_pows
。 I'm still pretty new to Haskell so I may have overlooked something obvious. 我仍然是Haskell的新手,所以我可能忽略了一些显而易见的事情。 Is this even possible?
这甚至可能吗?
The magic of the list monad: 列表monad的魔力:
ghci> let powers (a, b) = [a ^ n | n <- [0 .. b-1]] ghci> powers (2, 3) [1,2,4] ghci> map powers [(2, 3), (5, 3)] [[1,2,4],[1,5,25]] ghci> sequence it [[1,1],[1,5],[1,25],[2,1],[2,5],[2,25],[4,1],[4,5],[4,25]] ghci> mapM powers [(2, 3), (5, 3)] [[1,1],[1,5],[1,25],[2,1],[2,5],[2,25],[4,1],[4,5],[4,25]] ghci> map product it [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]
This probably deserves a bit more explanation. 这可能需要更多解释。
You could have written your own 你可以写自己的
cartesianProduct :: [[a]] -> [[a]]
cartesianProduct [] = [[]]
cartesianProduct (list:lists)
= [ (x:xs) | x <- list, xs <- cartesianProduct lists ]
such that 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]]
. 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]]
。
However, comprehensions and monads are intentionally similar. 然而, 理解和单子故意相似。 The standard Prelude has
sequence :: Monad m => [ma] -> m [a]
, and when m
is the list monad []
, it actually does exactly what we wrote above. 标准Prelude有
sequence :: Monad m => [ma] -> m [a]
,当m
是列表monad []
,它实际上完全按照我们上面所写的那样做。
As another shortcut, mapM :: Monad m => (a -> mb) -> [a] -> m [b]
is simply a composition of sequence
and map
. 作为另一种捷径,
mapM :: Monad m => (a -> mb) -> [a] -> m [b]
只是sequence
和map
的组合。
For each inner list of varying powers of each base, you want to multiply them to a single number. 对于每个基数的不同幂的每个内部列表,您希望将它们乘以一个数字。 You could write this recursively
你可以递归地写这个
product list = product' 1 list
where product' accum [] = accum
product' accum (x:xs)
= let accum' = accum * x
in accum' `seq` product' accum' xs
or using a fold 或使用折叠
import Data.List
product list = foldl' (*) 1 list
but actually, product :: Num a => [a] -> a
is already defined! 但实际上,
product :: Num a => [a] -> a
已经定义了! I love this language ☺☺☺ 我喜欢这种语言☺☺☺
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.