2

いくつかの入力セットでテストしたい関数があります。関数が

f :: a -> b -> c

これで、2 つの入力リストができました。

inputA :: [a]
inputB :: [[b]]

については、 のリストの各要素をinputA !! i評価したいと思います。これを行うには のいくつかのアプリケーションが必要であることはわかっていますが、解決策に頭を悩ませています。f $ input !! iinputB !! imap

私の最近の試みは

map f inputA <$> inputB

次のエラーが発生します。

a0 -> b0' with actual type予期された型[b1]と一致しませんでした' map の
呼び出しの戻り値の型で適用される引数が多すぎますmap の最初の引数でf inputA' 式で: map f inputA inputBmap'
Probable cause:

(<$>)', namely

この問題を解決するにはどうすればよいですか?私は必ずしも完全な解決策を求めているわけではありません。役立つ方向へのプッシュ (またはプッシュ) は、間違いなく高く評価されます。

追加の考え:

map f inputA :: [b -> c]

これは正しい方向だと思います。ここで、各関数を の各入力リストにマップする必要がありますinputB

明確にするために、入力のth リストにith 関数をマップして結果を取得したいと思います。map f inputAiinputBoutputC :: [[c]]

4

4 に答える 4

6

使用できますzipWith

Prelude> let a = [1,2,3]
Prelude> let b = [[1,2,3],[4,5,6],[7,8,9]]
Prelude> zipWith (\a' bl -> map (+a') bl)  a b
[[2,3,4],[6,7,8],[10,11,12]]
于 2013-10-05T07:02:30.833 に答える
3

リスト内包表記ですべてが簡単です。

g f xs yss = [ [f x y | y <- ys] | (x,ys) <- zip xs yss]
           = [ map    (f x)  ys  | (x,ys) <- zip xs yss]
           = [ map     fx    ys  | (fx,ys) <- zip (map f xs) yss]
           = zipWith map (map f xs) yss

           = [ (map . f) x   ys  | (x,ys) <- zip xs yss]
           = zipWith (map . f) xs yss

コメントで@nponeccopによって最初に示され、他の回答でも示唆された最後のもの。コード変換を使用してそれらから取得できます

map c' $ zip a b     == zipWith c a b   where  c' (a,b) = c a b
map (c a) b          == (map . c) a b
\ a b -> map (c a) b ==  map . c

あなたもそれの無意味なバージョンを見つけようとしたようです:

           = zipWith (map . f) xs yss
           = (zipWith . (map .)) f xs yss

eta-reduction によるものg = (zipWith . (map .))ですが、これは簡単には理解できないかもしれません。これはさらに難読化されzipWith <$> (map <$>)、さらにzipWith <$> ((<$>) <$>).

または、タイプ from を次のように使用できZipListますControl.Applicative

           = zipWith (map . f) xs yss
           = getZipList $ liftA2 (map . f)    (ZipList xs)    (ZipList yss)
           = getZipList $ pure   (map . f) <*> ZipList xs  <*> ZipList yss
           = getZipList $        (map . f) <$> ZipList xs  <*> ZipList yss
           = getZipList $       map <$> (f <$> ZipList xs) <*> ZipList yss
于 2013-10-05T10:44:52.433 に答える
1

私があなたを正しく理解しているなら、次のようなものです:

mapNested :: (a -> b -> c) -> [a] -> [[b]] -> [[c]]
mapNested f [] _ = []
mapNested f _ [] = []
mapNested f (x:xs) ys = concatMap (map (f x)) ys : mapNested f xs ys

Main> mapNested (+) [1, 2, 3] [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[2,3,4,5,6,7,8,9,10],[3,4,5,6,7,8,9,10,11],[4,5,6,7,8,9,10,11,12]]

これがあなたが探しているものではない場合、入力と出力の例を提供できますか?

編集

それとも、これはあなたが望んでいるものですか?

mapNested :: (a -> b -> c) -> [a] -> [[b]] -> [[c]]
mapNested f xs = zipWith map (map f xs)

Main> mapNested (,) [1, 2, 3] [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[(1,1),(1,2),(1,3)],[(2,4),(2,5),(2,6)],[(3,7),(3,8),(3,9)]]
于 2013-10-05T05:54:26.343 に答える