## 2017年2月9日木曜日

### Haskell - 単純なデータ型 - ブール値(相等性演算子(Eq)と比較演算子(Ord), 型クラス、インスタンスの宣言)

コード(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値であること

```

```\$ 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.
\$
```