mike-neckのブログ

Java or Groovy or Swift or Golang

『ふつうのHaskell』第10章〜第11章

第10章

エンティティ

モジュール定義

基本的な形

module Repository where

特定のエンティティのみエクスポートする

module Repository (findById, save) where

データコンストラクターのエクスポート

module Repository (Repo(UserRepo, TweetRepo), findById, save) where
    data Repo = UserRepo | TweetRepo

コンストラクターに対応するデータコンストラクターをエクスポートする場合

module Repository (Repo(..), findById, save) where

インポートしたモジュールのエンティティをエクスポートする場合

module Repository
    (module Data.List.map
        Repo(..), findById, save) where
import Data.List.map

インポート

-- Data.Listモジュールをインポート
import Data.List
-- 特定のエンティティをインポートおよび特定のエンティティ(下の例ではjoin)をインポートを防止
import Control.Monad (Monad, Maybe) hiding (join)
-- 完全修飾名でインポートすると完全修飾名でのみ関数などにアクセスするようになる(名前衝突の回避)
import qualified Text.Regex
-- 別名を与えてインポート
import GHC.IO.Encoding as Enc

第11章

Monad

Monadクラス

class Monad m where
    (>>=):: m a -> (a -> m b) -> m b
    return:: a -> m a

モナド

モナドは下記の法則を満たす

(return x) >>= f == f x
m >>= return == m
(m >>= f) >>= g == m >>= (\x -> f x >>= g)

Maybe

値の有無を表す。Nothingが値なし、Just aが値あり

定義

data Maybe a = Nothing | Just a deriving (Eq, Ord)
instance Monad Maybe where
    (Just x) >>= f = f x
    Nothing >>= _ = Nothing
    return x = Just x

簡単なMaybeの例

-- dictionaryを用意
myMap = [("bar", 1), ("baz", 2), ("foo", 3)]
-- 数字が奇数ならJust、偶数ならNothing
oddNum:: Int -> Maybe Int
oddNum n = case (mod n 2) of
    1 -> Just n
    0 -> Nothing
-- main
main = do
    print $ lookup "foo" myMap >>= oddNum  -- Just 3
    print $ lookup "baz" myMap >>= oddNum  -- Nothing
    print $ lookup "hoge" myMap >>= oddNum -- Nothing

リストMonad

定義

instance Monad [] where
    xs >>= f = concatMap f xs
    return x = [x]

IO Monad

更新後の世界とかよくわからんかった。とりあえず、副作用のある処理に活用できるらしい。