計算機科学のブログ

関数型プログラミングの基礎 関数と関数型プログラミング 関数型プログラミングの実用的価値 if文、then句、else句

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT1(関数型プログラミングの基礎)、LESSON 2(関数と関数型プログラミング)、2.3(関数型プログラミングの実用的価値)、練習問題Q2-1、Q2-2、Q2-3の解答を求めてみる。

Q2-1

elseが含まれていない場合、if文での評価が偽の時に関数が値を返さず、先の3つのルールの中の「関数は常に値を返さなければならない」を満たさなくなってしまう。

コード

-- Q2-2
inc :: Num a => a -> a
inc n = n + 1
double :: Num a => a -> a
double n = 2 * n
square :: Num a => a -> a
square n = n * n

-- Q2-3
f :: Integral a => a -> a
f n = if even n
    then n - 2
    else 3 * n + 1

入出力結果(Terminal, Zsh)

% ghci
GHCi, version 8.10.4: https://www.haskell.org/ghc/  :? for help
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
λ> :load sample2_2
[1 of 1] Compiling Main             ( sample2_2.hs, interpreted )
Ok, one module loaded.
(0.01 secs,)
*Main
λ> inc 0
1
it :: Num a => a
(0.01 secs, 62,128 bytes)
*Main
λ> inc 1
2
it :: Num a => a
(0.00 secs, 59,816 bytes)
*Main
λ> inc 2
3
it :: Num a => a
(0.00 secs, 59,816 bytes)
*Main
λ> inc 5
6
it :: Num a => a
(0.00 secs, 59,816 bytes)
*Main
λ> double 0
0
it :: Num a => a
(0.00 secs, 59,800 bytes)
*Main
λ> double 1
2
it :: Num a => a
(0.00 secs, 59,800 bytes)
*Main
λ> double 5
10
it :: Num a => a
(0.00 secs, 60,552 bytes)
*Main
λ> square 0
0
it :: Num a => a
(0.00 secs, 59,744 bytes)
*Main
λ> square -1

<interactive>:10:1: error:
    • Non type-variable argument in the constraint: Num (a -> a)
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall a. (Num a, Num (a -> a)) => a -> a
(0.00 secs,)
*Main
λ> square (-1)
1
it :: Num a => a
(0.00 secs, 59,816 bytes)
*Main
λ> square 1
1
it :: Num a => a
(0.00 secs, 59,744 bytes)
*Main
λ> square 5
25
it :: Num a => a
(0.00 secs, 60,496 bytes)
*Main
λ> :load sample2_2
[1 of 1] Compiling Main             ( sample2_2.hs, interpreted )
Ok, one module loaded.
(0.02 secs,)
*Main
λ> f 0
-2
it :: Integral a => a
(0.01 secs, 60,904 bytes)
*Main
λ> f 1
4
it :: Integral a => a
(0.00 secs, 60,256 bytes)
*Main
λ> f 2
0
it :: Integral a => a
(0.00 secs, 60,152 bytes)
*Main
λ> f 4
2
it :: Integral a => a
(0.00 secs, 60,152 bytes)
*Main
λ> f 5
16
it :: Integral a => a
(0.00 secs, 61,008 bytes)
*Main
λ> f -4

<interactive>:20:1: error:
    • Non type-variable argument in the constraint: Num (a -> a)
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall a. (Integral a, Num (a -> a)) => a -> a
(0.00 secs,)
*Main
λ> f (-4)
-6
it :: Integral a => a
(0.01 secs, 61,056 bytes)
*Main
λ> f (-5)
-14
it :: Integral a => a
(0.00 secs, 61,912 bytes)
*Main
λ> :q
Leaving GHCi.
%