コンテキストでの型の操作 Monad型クラス ApplicativeとFunctorの制限 2つのMap.lookupを組み合わせる
入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT5(コンテキストでの型の操作)、LESSON30(ApplicativeとFunctorの制限)、2つのMap.lookupを組み合わせる、クイックチェック 30-1の解答を求めてみる。
pure lookupCreditsの型はApplicative f => f (UserName -> Maybe PlayerCredits)になる。なので、creditsFromIdStringe idはMaybe (Maybe PlayerCredits)型を返すことになる。入れ子になるのが問題点。
実際に確認。
コード
import qualified Data.Map as Map
type UserName = String
type GameId = Int
type PlayerCredits = Int
userNameDB :: Map.Map GameId UserName
userNameDB = Map.empty
lookupUserName :: GameId -> Maybe UserName
lookupUserName id = Map.lookup id userNameDB
creditsDB :: Map.Map UserName PlayerCredits
creditsDB = Map.empty
lookupCredits :: UserName -> Maybe PlayerCredits
lookupCredits username = Map.lookup username creditsDB
creditsFromIdStrange :: GameId -> Maybe (Maybe PlayerCredits)
creditsFromIdStrange id = pure lookupCredits <*> lookupUserName id
入出力結果(Terminal, Zsh)
% ghci
GHCi, version 8.10.7: https://www.haskell.org/ghc/ :? for help
Loaded package environment from /Users/…/.ghc/x86_64-darwin-8.10.7/environments/default
:lomacro 'doc' overwrites builtin command. Use ':def!' to overwrite.
(0.00 secs, 0 bytes)
(0.00 secs, 0 bytes)
Loaded GHCi configuration from /Users/…/.ghc/ghci.conf
Prelude
λ> :load sample01.hs
[1 of 1] Compiling Main ( sample01.hs, interpreted )
Ok, one module loaded.
(0.07 secs,)
*Main
λ> creditsFromIdStrange 1
Nothing
it :: Maybe (Maybe PlayerCredits)
(0.02 secs, 67,736 bytes)
*Main
λ> pure lookupCredits
it :: UserName -> Maybe PlayerCredits
(0.01 secs, 58,608 bytes)
*Main
λ> :t pure lookupCredits
pure lookupCredits
:: Applicative f => f (UserName -> Maybe PlayerCredits)
*Main
λ> :quit
Leaving GHCi.
%