最初のクールなことは、a -> bサポートできることmapです。はい、関数はファンクターです!
のタイプを考えてみましょうmap:
map :: Functor f => (b -> c) -> f b -> f c
Functor f => f具体的な型をArray与えるために置き換えましょう:
map :: (b -> c) -> Array b -> Array c
今回Functor f => fは次のように置き換えます。Maybe
map :: (b -> c) -> Maybe b -> Maybe c
相関関係は明らかです。バイナリ型をテストするためFunctor f => fに, に置き換えましょう:Either a
map :: (b -> c) -> Either a b -> Either a c
a関数の型をからbとして表現することがよくありますa -> bが、それは の単なる砂糖ですFunction a b。Either長い形式を使用して、上記の署名をFunction次のように置き換えましょう。
map :: (b -> c) -> Function a b -> Function a c
b -> cしたがって、関数をマッピングすると、元の関数の戻り値に関数を適用する関数が得られます。a -> b砂糖を使用して署名を書き換えることができます。
map :: (b -> c) -> (a -> b) -> (a -> c)
何か気づきましたか?の型はcompose何ですか?
compose :: (b -> c) -> (a -> b) -> a -> c
関数型に特化したcomposeだけです!map
2 つ目のクールな点は、a -> bをサポートできることapです。関数もアプリカティブ ファンクターです。これらはFantasy Land 仕様ではApplyとして知られています。
のタイプを考えてみましょうap:
ap :: Apply f => f (b -> c) -> f b -> f c
Apply f => fに置き換えましょうArray:
ap :: Array (b -> c) -> Array b -> Array c
今、とEither a:
ap :: Either a (b -> c) -> Either a b -> Either a c
今、とFunction a:
ap :: Function a (b -> c) -> Function a b -> Function a c
とはFunction a (b -> c)? 2 つのスタイルを混在させているので少し混乱しますが、type の値を取り、 from toaの関数を返す関数です。スタイルを使って書き直してみましょう:bca -> b
ap :: (a -> b -> c) -> (a -> b) -> (a -> c)
map「持ち上げる」ことがapできるあらゆるタイプ。見てみましょうlift2:
lift2 :: Apply f => (b -> c -> d) -> f b -> f c -> f d
Function aは Apply の要件を満たしているので、次のように置き換えることApply f => fができFunction aます。
lift2 :: (b -> c -> d) -> Function a b -> Function a c -> Function a d
どちらがより明確に書かれています:
lift2 :: (b -> c -> d) -> (a -> b) -> (a -> c) -> (a -> d)
最初の式をもう一度見てみましょう。
// average :: Number -> Number
const average = lift2(divide, sum, length);
何をしaverage([6, 7, 8])ますか?a( ) が関数 ( ) に[6, 7, 8]与えられ、( )が生成されます。も関数 ( ) に与えられ、( ) が生成されます。これで aと aができたので、それらを関数 ( ) に渡して、最終結果である( ) を生成できます。a -> bsumb21aa -> clengthc3bcb -> c -> ddivided7
したがって、Function 型はmapおよびをサポートできるため、( 、、およびを介して) 無料でap取得できます。必要ないので、実際にはRamdaから削除したいと思います。convergeliftlift2lift3converge
R.liftこの回答では意図的に使用を避けたことに注意してください。任意のアリティの関数をサポートするという決定により、意味のない型シグネチャと複雑な実装があります。一方、Sanctuary のアリティ固有のリフティング関数には、明確な型シグネチャと単純な実装があります。