計算機科学のブログ

型の紹介 型クラス 必要な関数、インスタンス、Enum、Bounded、Eq、maxBound、minBound、succ

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT2(型の紹介)、LESSON 13(型クラス)、13.8 (練習問題)Q13-1の解答を求めてみる。

コード

-- Q13-1
-- WordとIntは同じinstanceだけど、minBoundとmaxBoundが異なる

-- Q13-2
inc :: Int -> Int 
inc = (+ 1)

-- Q13-3
cycleSucc :: (Bounded a, Enum a, Eq a) => a -> a
cycleSucc n =
    if n == maxBound
    then minBound
    else succ n

入出力結果(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
λ> :info Word
type Word :: *
data Word = GHC.Types.W# GHC.Prim.Word#
  	-- Defined in ‘GHC.Types’
instance Eq Word -- Defined in ‘GHC.Classes’
instance Ord Word -- Defined in ‘GHC.Classes’
instance Enum Word -- Defined in ‘GHC.Enum’
instance Num Word -- Defined in ‘GHC.Num’
instance Real Word -- Defined in ‘GHC.Real’
instance Show Word -- Defined in ‘GHC.Show’
instance Read Word -- Defined in ‘GHC.Read’
instance Bounded Word -- Defined in ‘GHC.Enum’
instance Integral Word -- Defined in ‘GHC.Real’
Prelude
λ> :info Int
type Int :: *
data Int = GHC.Types.I# GHC.Prim.Int#
  	-- Defined in ‘GHC.Types’
instance Eq Int -- Defined in ‘GHC.Classes’
instance Ord Int -- Defined in ‘GHC.Classes’
instance Enum Int -- Defined in ‘GHC.Enum’
instance Num Int -- Defined in ‘GHC.Num’
instance Real Int -- Defined in ‘GHC.Real’
instance Show Int -- Defined in ‘GHC.Show’
instance Read Int -- Defined in ‘GHC.Read’
instance Bounded Int -- Defined in ‘GHC.Enum’
instance Integral Int -- Defined in ‘GHC.Real’
Prelude
λ> :info Bound

<interactive>:1:1: error: Not in scope: ‘Bound’
Prelude
λ> :info Bounded
type Bounded :: * -> Constraint
class Bounded a where
  minBound :: a
  maxBound :: a
  {-# MINIMAL minBound, maxBound #-}
  	-- Defined in ‘GHC.Enum’
instance Bounded Word -- Defined in ‘GHC.Enum’
instance Bounded Ordering -- Defined in ‘GHC.Enum’
instance Bounded Int -- Defined in ‘GHC.Enum’
instance Bounded Char -- Defined in ‘GHC.Enum’
instance Bounded Bool -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e,
          Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k,
          Bounded l, Bounded m, Bounded n, Bounded o) =>
         Bounded (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e,
          Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k,
          Bounded l, Bounded m, Bounded n) =>
         Bounded (a, b, c, d, e, f, g, h, i, j, k, l, m, n)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e,
          Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k,
          Bounded l, Bounded m) =>
         Bounded (a, b, c, d, e, f, g, h, i, j, k, l, m)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e,
          Bounded f, Bounded g, Bounded h, Bounded i, Bounded j, Bounded k,
          Bounded l) =>
         Bounded (a, b, c, d, e, f, g, h, i, j, k, l)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e,
          Bounded f, Bounded g, Bounded h, Bounded i, Bounded j,
          Bounded k) =>
         Bounded (a, b, c, d, e, f, g, h, i, j, k)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e,
          Bounded f, Bounded g, Bounded h, Bounded i, Bounded j) =>
         Bounded (a, b, c, d, e, f, g, h, i, j)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e,
          Bounded f, Bounded g, Bounded h, Bounded i) =>
         Bounded (a, b, c, d, e, f, g, h, i)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e,
          Bounded f, Bounded g, Bounded h) =>
         Bounded (a, b, c, d, e, f, g, h)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e,
          Bounded f, Bounded g) =>
         Bounded (a, b, c, d, e, f, g)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e,
          Bounded f) =>
         Bounded (a, b, c, d, e, f)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e) =>
         Bounded (a, b, c, d, e)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c, Bounded d) =>
         Bounded (a, b, c, d)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b, Bounded c) => Bounded (a, b, c)
  -- Defined in ‘GHC.Enum’
instance (Bounded a, Bounded b) => Bounded (a, b)
  -- Defined in ‘GHC.Enum’
instance Bounded () -- Defined in ‘GHC.Enum’
Prelude
λ> minBound :: Word
0
it :: Word
(0.04 secs, 61,984 bytes)
Prelude
λ> minBound :: Int
-9223372036854775808
it :: Int
(0.00 secs, 73,680 bytes)
Prelude
λ> maxBound :: Word
18446744073709551615
it :: Word
(0.00 secs, 73,640 bytes)
Prelude
λ> maxBound :: Int
9223372036854775807
it :: Int
(0.00 secs, 72,904 bytes)
Prelude
λ> :info Enum
type Enum :: * -> Constraint
class Enum a where
  succ :: a -> a
  pred :: a -> a
  toEnum :: Int -> a
  fromEnum :: a -> Int
  enumFrom :: a -> [a]
  enumFromThen :: a -> a -> [a]
  enumFromTo :: a -> a -> [a]
  enumFromThenTo :: a -> a -> a -> [a]
  {-# MINIMAL toEnum, fromEnum #-}
  	-- Defined in ‘GHC.Enum’
instance Enum Word -- Defined in ‘GHC.Enum’
instance Enum Ordering -- Defined in ‘GHC.Enum’
instance Enum Integer -- Defined in ‘GHC.Enum’
instance Enum Int -- Defined in ‘GHC.Enum’
instance Enum Char -- Defined in ‘GHC.Enum’
instance Enum Bool -- Defined in ‘GHC.Enum’
instance Enum () -- Defined in ‘GHC.Enum’
instance Enum Float -- Defined in ‘GHC.Float’
instance Enum Double -- Defined in ‘GHC.Float’
Prelude
λ> :load sample1.hs 
[1 of 1] Compiling Main             ( sample1.hs, interpreted )
Ok, one module loaded.
(0.01 secs,)
*Main
λ> inc maxBound :: Int
-9223372036854775808
it :: Int
(0.00 secs, 73,776 bytes)
*Main
λ> succ maxBound :: Int
*** Exception: Prelude.Enum.succ{Int}: tried to take `succ' of maxBound
*Main
λ> succ 1
2
it :: (Enum a, Num a) => a
(0.00 secs, 59,760 bytes)
*Main
λ> :load sample1.hs 
[1 of 1] Compiling Main             ( sample1.hs, interpreted )
Ok, one module loaded.
(0.01 secs,)
*Main
λ> cycleSucc 1

<interactive>:15:1: error:
    • Ambiguous type variable ‘a0’ arising from a use of ‘print’
      prevents the constraint ‘(Show a0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘a0’ should be.
      These potential instances exist:
        instance (Show a, Show b) => Show (Either a b)
          -- Defined in ‘Data.Either’
        instance Show Ordering -- Defined in ‘GHC.Show’
        instance Show Integer -- Defined in ‘GHC.Show’
        ...plus 23 others
        ...plus 83 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In a stmt of an interactive GHCi command: print it
(0.01 secs,)
*Main
λ> cycleSucc 1 :: Int
2
it :: Int
(0.00 secs, 59,832 bytes)
*Main
λ> cycleSucc maxBound  :: Int
-9223372036854775808
it :: Int
(0.00 secs, 73,808 bytes)
*Main
λ> :quit
Leaving GHCi.
%