3

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ビルドせずに引数のペアをサポートできるようにします。私はまだHaskellにかなり慣れていないので、明らかなことを見落としている可能性があります。これは可能ですか?Nall_pows

4

1 に答える 1

11

リストモナドの魔法:

ghci> べき乗 (a, b) = [a ^ n | n <- [0 .. b-1]]
ghci> 累乗 (2, 3)
[1,2,4]
ghci> map powers [(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 powers [(2, 3), (5, 3)]
[[1,1]、[1,5]、[1,25]、[2,1]、[2,5]、[2,25]、[4,1]、[4,5]、[ 4,25]]
ghci> マップ製品 it
[1,5,25,2,10,50,4,20,100]
ghci> let allPowers リスト = マップ プロダクト $ mapM パワー リスト
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]]

ただし、内包表記とモナドは意図的に類似しています。標準の Preludeには があり、リスト モナドはsequence :: Monad m => [m a] -> m [a]whenであり、実際に上で書いたことを正確に実行します。m[]

別のショートカットとして、mapM :: Monad m => (a -> m b) -> [a] -> m [b]は単純に と を組み合わせたものsequenceですmap

各基数のさまざまな累乗の内部リストごとに、それらを 1 つの数値に乗算する必要があります。これを再帰的に書くことができます

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は、すでに定義されています! 私はこの言語が大好きです☺☺☺</p>

于 2010-02-27T21:39:35.463 に答える