fugafuga.write

日々のログ

すごいH本 part46

型シノニムの多相化

型シノニムに型引数をとることができる

type AssocList k v = [(k, v)]

型引数を部分適用すると新しい型コンストラクタが作れる

type IntMap v = Map Int v

こうも書ける

type IntMap = Map Int

Data.Map を修飾付インポートをする時は型コンストラクタの前にもモジュール名付ける必要がある。

type IntMap = Map.Map Int

Haskell のソースコードは値の領域、型の領域に分かれている。

  • 型の領域
    • データ型
    • 型シノニムの宣言
    • 型宣言や型注釈の :: の右側

Either型

Either は型引数を2つとる。定義は以下

data Either a b = Left a | Right b deriving (Eq, Ord, Read, Show)

Either型は2つの型のうちどちらか一方という値を表現できる。

*Main> Right 20
Right 20
*Main> Left "w00t"
Left "w00t"
*Main> :t Right 'a'
Right 'a' :: Either a Char
*Main> :t Left True
Left True :: Either Bool b

関数がなぜ失敗したのか、どのように失敗したのかを知りたい時にEither a b型の返り値を使う。 aは失敗が起こった場合に何であるかを伝えてくれる型、bは成功した計算の型。 エラーはLeft値コンストラクタ、結果はRight値コンストラクタを使って表現する。

ロッカーをMapで表現する

import qualified Data.Map as Map

data LockerState = Taken | Free deriving (Show, Eq)

type Code = String

type LockerMap = Map.Map Int (LockerState, Code)

ロッカーのCodeを検索する関数を作る

lockerLookup :: Int -> LockerMap -> Either String Code
lockerLookup lockerNumber map =
    case Map.lookup lockerNumber map of
      Nothing            -> Left $ "Locker " ++ show lockerNumber ++ " doesn't exist!"
      Just (state, code) -> if state /= Taken
                              then Right code
                              else Left $ "Locker " ++ show lockerNumber ++ " is already taken!"

ロッカーのデータはこれ

lockers :: LockerMap
lockers = Map.fromList
  [(100, (Taken, "ZD39I"))
  ,(101, (Free, "JAH3I"))
  ,(102, (Free, "POEG3"))
  ,(105, (Free, "HUYT3"))
  ,(109, (Taken, "MMNB7"))
  ,(110, (Taken, "QWEU9"))]

検索する

*Main> lockerLookup 101 lockers
Right "JAH3I"
*Main> lockerLookup 100 lockers
Left "Locker 100 is already taken!"
*Main> lockerLookup 102 lockers
Right "POEG3"
*Main> lockerLookup 103 lockers
Left "Locker 103 doesn't exist!"

結果を表現するのにMaybe aを使うとロッカーの取得に失敗しても原因が伝わらない。 Either a bを使うと失敗の情報も伝えることができる。

所感

データ型のパターンマッチで処理が分岐していく様がわかって楽しい。Either a b型とMaybe a型で何が表現できるのかというところの感覚をもう少し掴んでいく必要がある。この例に出てきた関数も自分で書くとなると難しそう。

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!

  • 作者: MiranLipovaca
  • 出版社/メーカー: オーム社
  • 発売日: 2017/07/14
  • メディア: Kindle版
  • 購入: 4人 クリック: 9回
  • この商品を含むブログを見る