【问题标题】:Dynamically build list comprehension in Haskell在 Haskell 中动态构建列表理解
【发布时间】:2010-02-27 21:27:14
【问题描述】:

我很好奇是否可以在 Haskell 中动态构建列表理解。

例如,如果我有以下情况:

all_pows (a,a') (b,b') = [ a^y * b^z | y <- take a' [0..], z <- take b' [0..] ]

我得到了我所追求的

*Main> List.sort $ all_pows (2,3) (5,3)
[1,2,4,5,10,20,25,50,100]

但是,我真正想要的是拥有类似的东西

all_pows [(Int,Int)] -> [Integer]

这样我就可以支持N 参数对,而无需构建N 版本的all_pows。我对 Haskell 还是很陌生,所以我可能忽略了一些明显的东西。这甚至可能吗?

【问题讨论】:

    标签: dynamic haskell list-comprehension


    【解决方案1】:

    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]]

    但是,comprehensionsmonads 故意相似。标准 Prelude 有 sequence :: Monad m =&gt; [m a] -&gt; m [a],当 m 是列表单子 [] 时,它实际上完全按照我们上面写的。

    作为另一个快捷方式,mapM :: Monad m =&gt; (a -&gt; m b) -&gt; [a] -&gt; m [b] 只是sequencemap 的组合。

    对于每个碱基的不同幂的每个内部列表,您希望将它们乘以一个数字。你可以递归地写这个

    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 =&gt; [a] -&gt; a 已经定义了!我喜欢这种语言☺☺☺

    【讨论】:

    • let powers (a, b) = [a ^ n | n &lt;- [0 .. b-1]]
    • @Tordek 谢谢,我浏览原文有点太快了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多