2017年2月9日木曜日

開発環境

関数プログラミング入門(Richard Bird (著)、山下伸夫 (翻訳)、オーム社)の第2章(単純なデータ型)、2.1(ブール値)、練習問題2.1.1、2.1.2、2.1.3、2.1.4、2.1.5、2.1.6、2.1.7、2.1.8、2.1.9を取り組んでみる。

練習問題2.1.1、2.1.2、2.1.3、2.1.4、2.1.5、2.1.6、2.1.7、2.1.8、2.1.9

コード(Emacs)

-- 2.1.1
(&&), (||):: Bool -> Bool -> Bool
x && y = if x then y else False
x || y = if x then True else y

-- 2.1.2
() :: Bool -> Bool -> Bool
x ⇨ y =  if x Main.&& (not y)
         then False
         else True

-- 2.1.3
class Eq a where
  (==), (/=) :: a -> a -> Bool
  x /= y = not (x Main.== y)

instance Main.Eq Bool where
  x == y = (x Main.&& y) Main.|| (not x Main.&& not y)

-- 2.1.4
data Triangle = Failure | Isosceles | Equilateral | Scalene

analyse :: (Integer, Integer, Integer) -> Triangle
analyse (x, y, z)
  | (x <= y) Main.&& (y <= z) = f (x, y, z)
  | (x <= z) Main.&& (z <= y) = f (x, z, y)
  | (y <= x) Main.&& (x <= z) = f (y, x, z)
  | (y <= z) Main.&& (z <= x) = f (y, z, x)
  | (z <= x) Main.&& (x <= y) = f (z, x, y)
  | (z <= y) Main.&& (y <= x) = f (z, y, x)
  where
    f :: (Integer, Integer, Integer) -> Triangle
    f (x, y, z)
      | (x + y) <= z = Failure
      | x Prelude.== z = Equilateral
      | (x Prelude.== y) Main.|| (y Prelude.== z) = Isosceles
      | otherwise = Scalene
  
-- 2.1.5
sort3 :: (Integer, Integer, Integer) -> (Integer, Integer, Integer)
sort3 (x, y, z)
  | (x <= y) Main.&& (y <= z) = (x, y, z)
  | (x <= z) Main.&& (z <= y) = (x, z, y)
  | (y <= x) Main.&& (x <= z) = (y, x, z)
  | (y <= z) Main.&& (z <= x) = (y, z, x)
  | (z <= x) Main.&& (x <= y) = (z, x, y)
  | (z <= y) Main.&& (y <= x) = (z, y, x)

analyse' :: (Integer, Integer, Integer) -> Triangle
analyse' (x, y, z) 
      | (x' + y') <= z' = Failure
      | x' Prelude.== z' = Equilateral
      | (x' Prelude.== y') Main.|| (y' Prelude.== z') = Isosceles
      | otherwise = Scalene
  where (x', y', z') = sort3 (x, y, z)

-- 2.1.6
instance Prelude.Eq Triangle where
  Failure == Failure = True
  Isosceles == Isosceles = True
  Equilateral == Equilateral = True
  Scalene == Scalene = True
  
instance Ord Triangle where
  Failure <= Isosceles = True
  Failure <= Equilateral = True
  Failure <= Scalene = True
  Isosceles <= Equilateral = True
  Isosceles <= Scalene = True
  Equilateral <= Scalene = True
  _ <= _ = False

-- 2.1.7 複素数は通常の意味での大小の比較の意味はない
-- 2.1.8 評価結果がBool値であること

入出力結果(Terminal, ghci)

$ ghci sample1.hs
GHCi, version 8.0.2: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Main             ( sample1.hs, interpreted )
Ok, modules loaded: Main.
*Main> True Main.&& True
True
*Main> True Main.&& False
False
*Main> True Main.|| False
True
*Main> False Main.|| False
False
*Main> False Main.|| True
True
*Main> True ⇨ False
False
*Main> True ⇨ True
True
*Main> False ⇨ True
True
*Main> False ⇨ False
True
*Main> True Main.== True
True
*Main> True Main./= True
False
*Main> analyse (3, 1, 2)

<interactive>:18:1: error:
    • No instance for (Show Triangle) arising from a use of ‘print’
    • In a stmt of an interactive GHCi command: print it
*Main> analyse (3, 1, 2) == Failure

<interactive>:19:19: error:
    Ambiguous occurrence ‘==’
    It could refer to either ‘Prelude.==’,
                             imported from ‘Prelude’ at sample1.hs:1:1
                             (and originally defined in ‘GHC.Classes’)
                          or ‘Main.==’, defined at sample1.hs:14:3
*Main> analyse (3, 1, 2) Prelude.== Failure
True
*Main> analyse (2, 1, 2) Prelude.== Isosceles
True
*Main> analyse' (2, 1, 2) Prelude.== Isosceles
True
*Main> Failure <= Isosceles
True
*Main> Isosceles <= Failure
False
*Main> :q
Leaving GHCi.
$ 

0 コメント:

コメントを投稿