Markdown形式のScalaコードを、実行した状態で吐き出すやつ。
```tut
1 + 1
```
そう、こんなふうに。
```scala
scala> 1 + 1
res0: Int = 2
```
Markdown形式のScalaコードを、実行した状態で吐き出すやつ。
```tut
1 + 1
```
そう、こんなふうに。
```scala
scala> 1 + 1
res0: Int = 2
```
前回はモノイド。今回はモナドです。
mappend
x = xなどPrelude Data.Monoid> [1,2,3] `mappend` [4,5,6] [1,2,3,4,5,6] Prelude Data.Monoid> getFirst $ First (Just 'a') `mappend` First (Just 'b') Just 'a'
import Data.Monoid import qualified Data.Foldable as F data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show) instance F.Foldable Tree where foldMap f EmptyTree = mempty foldMap f (Node x l r) = F.foldMap f l `mappend` f x `mappend` F.foldMap f r testTree = Node 5 (Node 3 (Node 1 EmptyTree EmptyTree) (Node 6 EmptyTree EmptyTree) ) (Node 9 (Node 8 EmptyTree EmptyTree) (Node 10 EmptyTree EmptyTree) ) main = do print $ F.foldr (+) 0 testTree print $ F.foldl (*) 1 testTree print $ getAny $ F.foldMap ( \ x -> Any $ x == 3) testTree print $ getAny $ F.foldMap ( \ x -> Any $ x > 15) testTree print $ F.foldMap ( \ x -> [x]) testTree
fmap :: (a -> b) -> f a -> f -- ファンクター (<*>) :: f (a -> b) -> f a -> f b -- アプリカティブファンクター (>>=) :: m a -> (a -> m b) -> m b -- モナド
Prelude Data.Monoid Control.Applicative> Just (+3) <*> Just 3 Just 6 Prelude Data.Monoid Control.Applicative> Nothing <*> Just "greed" Nothing
アプリカティブファンクターの例。
Prelude Data.Monoid Control.Applicative> ( \ x -> Just (x+1)) 1 Just 2
では、引数がMaybe値だったらどうするの?それを解決する答えが、モナドにある。
以下、オレオレバインド(>>=)の実装。 gist.github.com
引数は無名関数。
Prelude> :i Monad class Monad m where (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b return :: a -> m a fail :: String -> m a -- Defined in `GHC.Base' instance Monad Maybe -- Defined in `Data.Maybe' instance Monad (Either e) -- Defined in `Data.Either' instance Monad [] -- Defined in `GHC.Base' instance Monad IO -- Defined in `GHC.Base' instance Monad ((->) r) -- Defined in `GHC.Base'
Haskellのreturnは、値を文脈に入れて返すもので、他の言語のように関数の実行を中断させる命令ではない。
Prelude Control.Applicative Data.Monoid> :i >> class Monad m where ... (>>) :: m a -> m b -> m b ... -- Defined in `GHC.Base' infixl 1 >>
ロープ上のバナナは後述。
文脈を持った値を引数にとり、中身に関数を適用して文脈を持った値をそのまま返す例。
Prelude Control.Applicative Data.Monoid> Just 9 >>= \x -> return (x*10) Just 90 Prelude Control.Applicative Data.Monoid> Nothing >>= \x -> return (x*10) Nothing Prelude Control.Applicative Data.Monoid> return "WHAT" "WHAT" Prelude Control.Applicative Data.Monoid> return "WHAT" :: Maybe String Just "WHAT" Prelude Control.Applicative Data.Monoid> let (Just x) = Just 3 Prelude Control.Applicative Data.Monoid> x Prelude Control.Applicative Data.Monoid> let (Just x) = Nothing Prelude Control.Applicative Data.Monoid> x *** Exception: <interactive>:14:5-22: Irrefutable pattern failed for pattern (Data.Maybe.Just x) Prelude Control.Applicative Data.Monoid> Just 3 >> Just 4 Just 4 Prelude Control.Applicative Data.Monoid> Just 3 >> Nothing Nothing
putStrLnのはなし。値を取り出して、適用する。なお、putStrLnには戻り値がない。標準出力はその副作用。
Prelude Control.Applicative Data.Monoid> putStrLn "aaa" >>= \x -> return x aaa Prelude Control.Applicative Data.Monoid> putStrLn "aaa" aaa Prelude Control.Applicative Data.Monoid> :t putStrLn putStrLn :: String -> IO ()
ピエールの綱渡り。独習Scalazにもちょくちょく出てくる。
中野さん(仮)はバランス棒を持ちながら綱渡りをしているのだが、時たま鳥が棒の上で一休みすることがあり、鳥が棒の片サイドに集中して一休みすると中野さん(仮)はバランスを崩して転落してしまう。
このピエールの綱渡りをHaskellで実装してみる。
モナドの可換。図が狂ってる。
自己関手の圏 is 何
結合則があり、単位元があればモノイド。モノイド対象はモノイドと言い換えても良い。
モナドはモノイドの一種。。