簡単な意味は次のとおりです。

そして、関数を適用する方法を知っています。

小学校。 それでは、タスクを複雑にしてみましょう-コンテキストが重要です。 今のところ、コンテキストは単に値を入力できるボックスと考えることができます。

これで、この値に関数を適用する
と、コンテキストに応じて異なる結果が得られ
ます 。 これは、ファンクター、適用ファンクター、モナド、矢印などが基づいている主要なアイデアです。
Maybeデータ型は2つの関連するコンテキストを定義します:

data Maybe a = Nothing | Just a
後で、
Just a vs
Nothing関数の動作の違いを確認します。 しかし、最初にファンクターについて話しましょう!
ファンクター
コンテキストに値がパックされている場合、通常の関数を取得して適用することはできません。

そして、ここで
fmap助けを急いでいます。
fmap通りの男、
fmapはコンテキストについて多くのことを知っています。 彼はすでに、コンテキストにパックされた値に関数を適用する方法を知っています。
Just 2 (+3)を適用するとします。
fmap使用します。
> fmap (+3) (Just 2) Just 5
バム! fmapはその方法を示しました! しかし、彼はどのように関数を正しく適用するかをどのように知っていますか?
それでは、実際にファンクターとは何ですか?
ファンクターは
型クラスです。 彼の定義は次のとおりです。

ファンクターは、
fmapがどのように適用されるかが決定されるデータ型です。 そして、これが
fmap仕組みです:

だから私たちにできることは:
> fmap (+3) (Just 2) Just 5
また、
fmapファンクタである可能性があるため、この関数
fmap魔法のように適用します。
Just and
Nothing関数を適用する方法を定義します:
instance Functor Maybe where fmap func (Just val) = Just (func val) fmap func Nothing = Nothing
これは、
fmap (+3) (Just 2)を記述するときにバックグラウンドで発生することです。

そして、あなたは言う:「さて、
fmap 、しかし
Nothing適用し
Nothingください
(+3) 。」

> fmap (+3) Nothing Nothing
ビル・オライリーは、おそらくファンクターには意味がないThe MatrixのMorpheusと同様に、
fmap何をすべきかを知っています。 あなたは
Nothingで始まり、
Nothingでも終わりました! これは
fmap zenです。 そして今、一般に
Maybeデータ型が存在する理由が明らかになりました。 ここで、たとえば、
Maybeせずに言語でデータベースへの書き込みをどのように処理します
Maybe :
post = Post.find_by_id(1) if post return post.title else return nil end
Haskellの場合:
fmap (getPostTitle) (findPost 1)
findPostがメッセージを返す場合、
findPostを使用してヘッダーを
getPostTitleます。 彼が
Nothingを返すなら、私たちは
Nothingを返します! くそー、エレガント?
<$>は
fmap挿入形です。そのため、上記のコードの代わりに次のコードを見つけることができます。
getPostTitle <$> (findPost 1)
別の例を次に示します。関数をリストに適用するとどうなりますか?

リストもファンクターです! 定義は次のとおりです。
instance Functor [] where fmap = map
わかりました、わかりました、もう1つ(最後の)例:関数を別の関数に適用するとどうなりますか?
fmap (+3) (+1)
関数は次のとおりです。

そして、これは別の関数に適用される関数です:

結果は単なる別の機能です!
> import Control.Applicative > let foo = fmap (+3) (+2) > foo 10 15
関数もファンクターです!
instance Functor ((->) r) where fmap fg = f . g
また、関数に
fmapを適用すると、関数を作成するだけです!
応用ファンクター
次のレベルは、アプリカティブファンクターです。 それらによって、私たちの価値はまだコンテキストに詰め込まれています(ファンクターの場合と同様):

しかし今、私たちの関数はコンテキストに詰め込まれています!

うん! これを始めましょう。 応用ファンクターは詐欺に関与しません。
Control.Applicativeは、
コンテキストでパッケージ化された関数
をコンテキストで パッケージ化された値に適用する方法を知っている
<*>を定義
します 。

つまり
Just (+3) <*> Just 2 == Just 5
<*>を使用すると、興味深い状況につながる可能性があります。 例:
> [(*2), (+3)] <*> [1, 2, 3] [2, 4, 6, 4, 5, 6]

そして、ここにあなたが適用可能なファンクターの助けを借りてできることがありますが、普通のファンクターの助けを借りてはできません。 2つの引数を2つのパック値に取る関数をどのように適用しますか?
> (+) <$> (Just 5) Just (+5) > Just (+5) <$> (Just 4) ??? JUST
適用可能なファンクター:
> (+) <$> (Just 5) Just (+5) > Just (+5) <*> (Just 3) Just 8
Applicative Functorを技術的に押しのけます。 「大物は、任意の数の引数を持つ関数を使用できます」と彼は言います。 「
<$>と
<*>で武装しているので、任意の数のアンパックされた引数を予期する関数を使用できます。 次に、すべてのパックされた値を彼女に渡し、パックされた結果を取得します! BWAHAHAHAHAHA!」
> (*) <$> Just 5 <*> Just 3 Just 15
応用ファンクタは、正規関数がどのように関数を適用するかを観察しますそしてはい! 同じことを行う
liftA2関数があります。
> liftA2 (*) (Just 5) (Just 3) Just 15
モナド
モナドを学ぶ方法:
- コンピューターサイエンスで博士号を取得
- このセクションを読むときにそれらは必要ないので、彼らにnafigを投げてください!
モナドはプロットに新しいひねりを加えます。
ファンクターは、パックされた値に通常の関数を適用します。

適用可能なファンクターは、パック関数をパック値に適用します。

モナド
は、パックされた値を
パックされた値に
戻す関数
を適用します。 モナドには関数
>>= (「バインディング」と発音します(
バインド ))があり、これを行うことができます。
この例を考えてみましょう:私たちの古き良き
Maybeはモナドです:
ぶら下がりモナドhalfを偶数でのみ機能する関数とします。
half x = if even x then Just (x `div` 2) else Nothing

しかし、パックされた値を彼女に与えるとどうなりますか?

関数でパックされた値をプッシュするには、
>>=を使用する必要があります。 写真はこちら
>>= :

そして、これがどのように機能するかです:
> Just 3 >>= half Nothing > Just 4 >>= half Just 2 > Nothing >>= half Nothing
内部で何が起こっているのですか?
Monadは別の型クラスです。 部分的な定義は次のとおりです。
class Monad m where (>>=) :: ma -> (a -> mb) -> mb
ここで
>>= :

だから
Maybeモナドです:
instance Monad Maybe where Nothing >>= func = Nothing Just val >>= func = func val
しかし、貧しい
Just 3に対してどのようなアクションが行われているのでしょうか。

入力に
Nothingを渡すと、さらに簡単になります。

一連の呼び出しをリンクすることもできます。
> Just 20 >>= half >>= half >>= half Nothing


かっこいい! そして今、
Maybeが
Functor 、
Applicative 、そして
Monad 1つになっていることがわかりました。
それでは、別の例に切り替えましょう:
IOモナド:

特に、3つの機能。
getLineは引数を取らず、入力からユーザーデータを受け取ります。

getLine :: IO String
readFileは文字列(ファイル名)を取り、その内容を返します。

readFile :: FilePath -> IO String
putStrLnは文字列を取り、それを出力します:

putStrLn :: String -> IO ()
3つの関数はすべて、通常の値(または値なし)を取り、パックされた値を返します。 したがって、
>>=を使用してそれらをチェーンできます!

getLine >>= readFile >>= putStrLn
はい、モナドショーの最前列のチケットがあります!
Haskellは、
do記法と呼ばれるモナドの構文糖衣も提供します。
foo = do filename <- getLine contents <- readFile filename putStrLn contents
おわりに
- ファンクターは、
Functor型クラスを使用して実装されるデータ型です - Applicative Functorは、
Applicative型クラスを使用して実装されるデータ型です - Monadは、
Monad型クラスを使用して実装されるデータ型です。 - 3種類すべてのタイプを使用して実装される可能性があるため、同時にファンクター、適用ファンクター、およびモナドです
3つの違いは何ですか?

- functor :
fmapまたは<$>を使用して、パックされた値に関数を適用します - applicative functor :
<*>またはliftAを使用して、パックされた値にパックされた関数を適用します liftM >>=またはliftMを使用して、パックされた値をパックされた値に返す関数を適用します
だから、親愛なる友人(そして、この瞬間までに友人になったことを願っています)、私はモナドがシンプルでスマートなアイデア(tm)であることに全員が同意すると思います。 そして今、このガイドで喉を濡らした後、メルギブソンに電話してボトルを仕上げてみませんか? LYAHのモナド
セクションをご覧ください。 Miranがこの資料を深める素晴らしい仕事をしてくれたので、私が言及しなかったことがたくさんあります。
さらに多くのモナドと写真が
3つの便利なモナドにあります (
翻訳 )。
翻訳者から:
オリジナルへのリンク: http ://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html HabrはURLをカンマで誓うので、このように書きます。
そしてもちろん、翻訳に関するPMのコメントに非常に感謝します。