計算機科学のブログ

コンテキストでの型の操作 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.
%