クリス・テイラーの答えはちょうどいいですが、それを見て別の方法、私はより直感的に見つけること、これである:同じ
- 「フィード」:どのような関数型の
Applicative
インスタンスがないことはこれです同じ引数型を持つ2つの関数への引数値。
- その結果を別の関数と組み合わせます。
あなたはf :: t -> a
とg:: t -> b
を持っているのであれば基本的には、Applicative
インスタンスは、あなたがf
とg
は同じ引数を供給することになるという仮定の下で、a
とb
結果オーバー機能h :: a -> b -> c
をマッピングすることができます。
ですから、非複雑な方法で回文テストを書きたいかを考える:
palindrome :: Eq a => [a] -> Bool
palindrome xs = xs == reverse xs
xs
は、定義の右側に2回表示:一度==
への引数、第二として、時間はreverse
の引き数になります。これにより、アプリケーションインスタンス(->) t
を使用して重複を排除する方法があることが自動的に伝えられます。
palindrome xs = id xs == reverse xs
... id x = x
はちょうどその引数を返します(標準ライブラリ関数である恒等関数、次のとおりです。この上の異なる、おそらくより直感的な攻撃は、最初にこのする機能を書き換えることであろう)。
-- Function that feed the same argument value to both `id` and `reverse`,
-- then tests their results with `==`:
palindrome = (==) <$> id <*> reverse
をそして、その書き換えにid
を取り除く方法がある場合、今、私たちは尋ねることができます:今、あなたは、これに標準Applicative
イディオム(f <$> a0 <*> ... <*> an
)を使用していることを書き換えることができます。 <$>
がfmap
のためだけの省略形ですので、我々は関数合成を表現するもうひとつの方法である、(->) t
ためFunctor
インスタンスを学ぶことができます。
instance Functor ((->) t) where
-- Mapping `f` over a *function* `g` is just the same as composing `f`
-- on the results of `g`.
fmap f g = f . g
機能組成物の最も重要な特性の1つは、任意の関数f
のためということです。
f . id = f
したがって、上記のpalindrome
のバージョンにそれを適用し、我々が得る:
-- Since `f . id = f` for all `f`, then `(==) <$> id` is just `(==)`:
palindrome = (==) <*> reverse
どうしてあなたはいつもきれいで分かりやすい答えを出さなければならないのですか? – dfeuer
2ヶ月後にそれに戻ってくることははるかに理にかなっています。ありがとう! – m0meni