2017-09-20 8 views
3

、bは文字列のリストであると考える機能組成

map (map (\a -> ((head a), (length a))) . group . sort) (transpose b)

を想定私は上記の個々の機能が何を知っているが、私は、トラブルの結果が組み立てられる方法を見てを抱えています。この行の関数がどのパラメータで実行されるかの順序を調べるにはどうすればよいですか?

具体的には、(map (\a -> ((head a), (length a))) . group . sort)が外側のマップの最初のパラメータで、(transpose b)が外側のマップの2番目のパラメータであることがわかりました。

しかし、これは内側のマップのパラメータですか?内側のマップは、ただ1つのパラメータ:(\a -> ((head a), (length a))) . group . sort)を持つように見えます。 2番目のパラメータはどこにありますか(要素を適用するリスト、最初のパラメータの関数)

+0

[ハスケルの可能な複製 - 小さなコードの理解に問題がある](https://stackoverflow.com/questions/46131310/haskell-having-trouble-understanding-a-small-bit-of-code) –

答えて

1

あなたが気づいたことはcurryingと呼ばれ、Haskellの機能の多くの素晴らしい(または多分ではない)側面の1つです。これはあなたのコードです:

map (map (\a -> ((head a), (length a))) . group . sort) (transpose b) 

は、まずはmapの種類を確認してみましょう:

map (\a -> ((head a), (length a))) :: [[a]] -> [(a, Int)] 

我々はGHCiのにこの

:t map (\a -> ((head a), (length a))) 

を入力してそう。

これは機能だとわかっています。型は[[a]]で、[(a, Int)]を返します。地図の種類を指定する関数は

map :: (a -> b) -> [a] -> [b] 

です。私たちはmapを与えています。それは最初の議論です。今、必要なものはすべて適切なリストです。地図で起こったことはcurryingと呼ばれています。

今、私たちは持っている、見てみましょう私たちのmap(.)機能を通じてsortgroupに「接続」。

l
(.) :: (b -> c) -> (a -> b) -> a -> c 

ここで、コードを少し変更して、構成機能で何が起こっているかを見てみましょう。

map (\a -> ((head a), (length a))) . (group . sort) 

私はいくつかの括弧でgroupsortを分離しました。しかし、今では、どの要素が外部の引数として機能しているかを明確に確認しています。(.)

問題のマップと、もう1つの構成の結果である別の機能があります。

map (\a -> ((head a), (length a))) . (group . sort) 
:: Ord a => [a] -> [(a, Int)] 

が最後に外mapは上から機能を取り込み、リスト(transpose b):我々は最後の引数を省略する場合、再び我々は、動作中のカリー化を持っています。

1

は暗黙的にです。あなたが書く場合:

と同等です
\b -> (map (\a -> ((head a), (length a))) . group . sort) b 

:これ

\b -> map (\a -> ((head a), (length a))) (group (sort b)) 

(.) :: (b -> c) -> (a -> b) -> a -> cオペレータ、:

\b -> map (\a -> ((head a), (length a))) $ group $ sort b 

または

map (\a -> ((head a), (length a))) . group . sort 

をこれは実際の略です2つの関数を合成する私たちはここに、ドットで区切られた3つの機能を記述しているので

(.) f g x = f (g x) 

:THERパイプラインのいくつかの並べ替えに

map (\a -> ((head a), (length a))) . group . sort 
-- \_________________ ______________/ \_ _/ \_/
--     v     v  v 
--     f     g  h 

を、私たちはその結果、その後、要素は最初hを介して処理されるパイプラインのいくつかの並べ替えを定義していますgによって処理され、最後にその結果がfによって処理されます。このように定義された

1

ドットが自身である関数:

(f . g) x = f (g x) 

さんは、外側マップの最初の引数には、この式を使用してみましょう:

map (\a -> (head a, length a)) . group . sort 
= { definition of (.), with map (\a -> ...) as f and group . sort as g } 
\x -> map (\a -> (head a, length a)) ((group . sort) x) 

ので、map (\a -> ...) . group . sortは関数であり、引数xに適用すると、引数として(group . sort) xmap (\a -> ...)に供給します。

関連する問題