[解決済み] Haskellのドット演算子:もっと説明が欲しい
質問
このHaskellのコードでドット演算子が何をしているのか理解しようとしています。
sumEuler = sum . (map euler) . mkList
ソースコード全体は以下の通りです。
私の理解
ドット演算子は、2つの関数
sum
の結果であり
map euler
の結果と
mkList
を入力とする。
しかし
sum
は関数ではありません......関数の引数ですよね?では、ここはどうなっているのでしょうか?
また、何が
(map euler)
は何をしているのでしょうか?
コード
mkList :: Int -> [Int]
mkList n = [1..n-1]
euler :: Int -> Int
euler n = length (filter (relprime n) (mkList n))
sumEuler :: Int -> Int
sumEuler = sum . (map euler) . mkList
どのように解決するのですか?
簡単に言うと
.
は数学と同じように関数の合成です。
f (g x) = (f . g) x
あなたの場合、新しい関数を作成しています。
sumEuler
という関数がありますが、これもこのように定義することができます。
sumEuler x = sum (map euler (mkList x))
この例のスタイルは "point-free" スタイルと呼ばれ、関数への引数が省略されています。 これは多くの場合、より明確なコードになります。 (初めて見たときは理解するのが難しいかもしれませんが、しばらくすると慣れるでしょう。 Haskellのイディオムとして一般的なものです)。
それでもまだ混乱しているのであれば、関連する
.
をUNIXのパイプのようなものに関連付けることができるかもしれません。 もし
f
の出力が
g
の入力となり、その出力は
h
の入力になるように、コマンドラインで次のように書きます。
f < x | g | h
. Haskellでは
.
はUNIXの
|
と同じように働きますが、quot;backwards" -- です。
h . g . f $ x
. この記法は、例えばリストを処理するときに非常に役に立つと思います。 例えば、リストを処理するときに、この記法はとても便利です。
map (\x -> x * 2 + 10) [1..10]
のような扱いにくい構文ではなく、単に
(+10) . (*2) <$> [1..10]
. (そして、その関数を一つの値だけに適用したい場合;それは
(+10) . (*2) $ 10
. 一貫しています!)
Haskellのwikiに、もう少し詳しい記事があります。 http://www.haskell.org/haskellwiki/Pointfree
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 一般的に `{- |` で始まるHaskellのコメントは何を意味するのですか?
-
[解決済み] Haskell - Ord aの型は何を意味するのでしょうか?
-
[解決済み] 機能における非網羅的なパターン【重複あり
-
[解決済み] Haskellで "length "関数を使用しない場合のリストの長さ
-
[解決済み] Haskell タプルをリスト化する?
-
[解決済み] Haskellで副作用がモナドとしてモデル化されているのはなぜですか?
-
[解決済み] 制約条件付き特殊化
-
[解決済み] Haskellのリストを参照する際の「@」記号の意味は?
-
[解決済み] Haskell型とデータコンストラクタ
-
[解決済み] Haskellの合成演算子(.)とF#のパイプ転送演算子(|>)の比較