Chapter 2 Talking About Mathematical Objects

module TAMO

where

someFuncTAMO :: IO ()
someFuncTAMO = putStrLn "TAMO"

{-
向きによらない中置演算子の定義
x ==> y
(==>) x y
は同じ
演算子には、優先順位を表す自然数をつける
-}

infix 1 ==>

(==>) :: Bool -> Bool -> Bool
x ==> y = (not x) || y

{-
True ==> x =x
False ==> x = True

という定義でもよい
-}

infix 1 <=>
(<=>) :: Bool -> Bool -> Bool
x <=> y = x == y

infixr 2 <+>
(<+>) :: Bool -> Bool -> Bool
x <+> y = x /= y
{-
p,q :: Bool
のようにタイプsignatureを書いてもよいが
型判定できる(に決まっている)ので書かなくても良い
-}
p = True
q = False

-- formula1 :: Bool
formula1 = (not p) && ( p ==> q ) <=> not ( q && ( not p))
-- formula2 :: Bool -> Bool -> Bool
formula2 p q = ((not p) && ( p ==> q ) <=> not ( q && ( not p)))

{-
二次方程式を解く
a x^2 + b x + c = 0から
x1,x2 = (-b +/- sqrt(4 a c - b^2))/(2 a)
を導く
引数と返り値にタプルが取れる
-}

solveQdr' :: (Float, Float, Float) -> (Float, Float)
solveQdr' (a, b, c) | a == 0 = error "not quadratic"
                   | b^2 - 4 * a * c < 0 = error "no real solutions"
                   | otherwise = (( - b + sqrt d) / (2 * a), (- b - sqrt d) / (2 * a)) where d = b^2 - 4 * a * c

{-
ラムダ式で書く
ラムダ式で書くとき、 whereは使えない模様
なのでlet ... in で書く
また、if then (if then)のような書き方より
   |
   |
   |
のような書き方の方が好きだが、ラムダ式では対応できない
syntax extensionの LambdaCaseというのを使うと良いらしいのだが
うまく行かない
-}

solveQdr :: (Float, Float, Float) -> (Float, Float)
solveQdr = \ (a, b, c)  -> 
                let d = b^2 - 4 * a * c
                in 
                   if a == 0
                        then error "not quadratic"
                        else 
                            if d < 0
                               then error "no real solutions"
                               else (( - b + sqrt d) / (2 * a), (- b - sqrt d) / (2 * a))