```-- |
-- TFwH 第2章 式,型,値
--
module TFwH.Chap02
( -- * 2 式,型,値
-- ** 2.1 GHCiを使ったセッション
-- ** 2.2 名前と演算子
(+++)
-- ** 2.3 評価
, sqr
, infinity
, three
, factorial
, fact
, to
-- ** 型と型クラス
, Pin
, Person(..)
, samePerson
-- ** 値の表示
, cwords
, roots
) where

import TFwH.CommonWords

-- |
-- ユーザ定義演算子
--
(+++) :: Int -> Int -> Int
x +++ y = if even x then y else x + y

-- |
-- 整数の2乗
--
sqr :: Integer -> Integer
sqr x = x * x

-- |
-- 無限大
--
infinity :: Integer
infinity = 1 + infinity

-- |
-- 常に3になる定数関数
--
three :: Integer -> Integer
three x = 3

-- |
-- 階乗関数
--
factorial :: Integer -> Integer
factorial n = fact (n, 1)

-- |
-- 下請け関数
--
fact :: (Integer, Integer) -> Integer
fact (x, y) = if x == 0 then y else fact (x - 1, x * y)

-- |
-- 無限ループする関数
--
to :: Bool -> Bool
to b = not (to b)

-- |
-- Person(例)
--
data Person = Person { pin :: Pin }
type Pin = Int

instance Eq Person where
x == y = pin x == pin y

samePerson :: Person -> Person -> Bool
samePerson x y = pin x == pin y

-- |
-- 頻出単語
--
cwords :: Int -> FilePath -> FilePath -> IO ()
cwords n infile outfile
= do { text <- readFile infile
; writeFile outfile (commonWords n text)
; putStrLn "cwords done!"
}

main :: IO ()
main = do { putStrLn "Take text from where:"
; infile <- getLine
; putStrLn "How many words:"
; n <- getLine
; putStrLn "Put results where:"
; outfile <- getLine
; writeFile outfile (commonWords (read n) text)
; putStrLn "cwords done!"
}

-- |
-- 2次方程式の解
--
roots :: (Float, Float, Float) -> (Float, Float)
roots (a, b, c)
| a == 0 = error "not quadratic"
| disc < 0 = error "complex roots"
| otherwise = ((-b - r) / e, (-b + r) / e)
where
{ disc = b * b - 4 * a * c; r = sqrt disc; e = 2 * a }
```