計算機科学のブログ

コンテキストでの型の操作 Applicative型クラス:関数をコンテキスト内で使用する コンテキストでの部分適用に<*>を使用する <*>演算子、<$>と<*>を使って複数の引数を持つ関数をIOで呼び出す

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT5(コンテキストでの型の操作)、LESSON 28(Applicative型クラス:関数をコンテキスト内で使用する)、28.2(コンテキストでの部分適用に<>を使用する)の<>演算子のクイックチェック28-3、<$>と<*>を使って複数の引数を持つ関数をIOで呼び出すのクイックチェック28-4の解答を求めてみる。

コード

-- クイックチェック 28-4
minOfThree :: (Ord a) => a -> a -> a -> a
minOfThree x y z = min x (min y z)

main :: IO ()
main = do
    print (minOfThree <$> Just 10 <*> Just 3 <*> Just 6)

入出力結果(Terminal, Zsh)

% ghci
GHCi, version 8.10.5: https://www.haskell.org/ghc/  :? for help
Loaded package environment from /…/.ghc/x86_64-darwin-8.10.5/environments/default
macro 'doc' overwrites builtin command.  Use ':def!' to overwrite.
(0.00 secs, 0 bytes)
(0.00 secs, 0 bytes)
Loaded GHCi configuration from /…/.ghc/ghci.conf
Prelude
λ> (*) <$> Just 2 <*> Just 3
Just 6
it :: Num b => Maybe b
(0.03 secs, 66,664 bytes)
Prelude
λ> (*) <$> Just 2 <*> Nothing
Nothing
it :: Num b => Maybe b
(0.01 secs, 64,640 bytes)
Prelude
λ> (*) <$> Nothing  <*> Just 3
Nothing
it :: Num b => Maybe b
(0.01 secs, 64,072 bytes)
Prelude
λ> :t div
div :: Integral a => a -> a -> a
Prelude
λ> div <$> Just 2 <*> 3

<interactive>:5:1: error:
    • Non type-variable argument in the constraint: Num (Maybe b)
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall b. (Integral b, Num (Maybe b)) => Maybe b
(0.01 secs,)
Prelude
λ> div <$> Just 2 <*> Just 3
Just 0
it :: Integral b => Maybe b
(0.01 secs, 64,048 bytes)
Prelude
λ> div <$> Just 4 <*> Just 2
Just 2
it :: Integral b => Maybe b
(0.01 secs, 64,048 bytes)
Prelude
λ> mod <$> Just 2 <*> Just 3
Just 2
it :: Integral b => Maybe b
(0.01 secs, 64,048 bytes)
Prelude
λ> mod <$> Just 4 <*> Just 2
Just 0
it :: Integral b => Maybe b
(0.01 secs, 64,048 bytes)
Prelude
λ> mod <$> Just 4 <*> Just 3
Just 1
it :: Integral b => Maybe b
(0.01 secs, 64,048 bytes)
Prelude
λ> :quit
Leaving GHCi.
% runghc sample04.hs
Just 3
%