写真のファンクター、適用ファンクター、モナド

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





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





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





これで、この値に関数を適用すると、コンテキストに応じて異なる結果が得られます 。 これは、ファンクター、適用ファンクター、モナド、矢印などが基づいている主要なアイデアです。 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
      
      







モナド



モナドを学ぶ方法:

  1. コンピューターサイエンスで博士号を取得
  2. このセクションを読むときにそれらは必要ないので、彼らに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
      
      







おわりに



  1. ファンクターは、 Functor



    型クラスを使用して実装されるデータ型です
  2. Applicative Functorは、 Applicative



    型クラスを使用して実装されるデータ型です
  3. Monadは、 Monad



    型クラスを使用して実装されるデータ型です。
  4. 3種類すべてのタイプを使用して実装される可能性があるため、同時にファンクター、適用ファンクター、およびモナドです


3つの違いは何ですか?









だから、親愛なる友人(そして、この瞬間までに友人になったことを願っています)、私はモナドがシンプルでスマートなアイデア(tm)であることに全員が同意すると思います。 そして今、このガイドで喉を濡らした後、メルギブソンに電話してボトルを仕上げてみませんか? LYAHのモナドセクションをご覧ください。 Miranがこの資料を深める素晴らしい仕事をしてくれたので、私が言及しなかったことがたくさんあります。

さらに多くのモナドと写真が3つの便利なモナドにあります翻訳 )。



翻訳者から:

オリジナルへのリンク: http ://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html HabrはURLをカンマで誓うので、このように書きます。

そしてもちろん、翻訳に関するPMのコメントに非常に感謝します。



All Articles