# 初探變數與函式

January 29, 2022

``````import System.IO

main = do
putStr "請輸入整數："
hFlush stdout
input <- getLine
result = if number `mod` 2 == 0 then "偶數" else "奇數"
putStrLn (input ++ "是 " ++ result ++ "！")
``````

``````>ghc is_odd.hs
[1 of 1] Compiling Main             ( is_odd.hs, is_odd.o )

>is_odd

10 是偶數！

>is_odd

5 是奇數！
``````

## let 關鍵字

``````ghci> let a = 10 in a + 20
30
ghci> a

<interactive>:2:1: error: Variable not in scope: a
ghci>
``````

``````main = do
let a = 10
a = a + a
putStrLn a
``````

``````test.hs:2:9: error:
Conflicting definitions for ‘a’
Bound at: test.hs:2:9
test.hs:3:9
|
2 |     let a = 10
|         ^^^^^^^...
``````

``````ghci> let a = 10
ghci> a = a + a
ghci>
``````

``````ghci> let n = read "10"
ghci> n
ghci>
``````

``````ghci> let n = read "10" :: Int
ghci> n
10
ghci>
``````

`mod` 函式是餘除函式，它會傳回兩數相除後的餘數，可以使用 `mod 10 2` 呼叫函式，表示要計算出 `10` 除以 `2` 的餘數，askell 函式的指定引數時，並不使用括號，若希望這類有兩個引數的函式呼叫，可以比較像數學上的二元運彪，可以使用使用 ``` 來括住函式：

``````ghci> mod 10 2
0
ghci> 10 `mod` 3
1
ghci>
``````

``````ghci> if True then 10 else 20
10
ghci> if False then 10 else 20
20
ghci>
``````

## 定義函式

``````import System.IO

isOdd n =
n `mod` 2 == 0

evenOdd n =
if (isOdd n) then "偶數" else "奇數"

in input ++ "是 " ++ (evenOdd n) ++ "！"

prompt text = do
putStr text
hFlush stdout

main = do
prompt "請輸入整數："
input <- getLine
``````

``````import System.IO

isOdd :: Int -> Bool
isOdd n =
n `mod` 2 == 0

evenOdd :: Int -> String
evenOdd n =
if (isOdd n) then "偶數" else "奇數"

in input ++ "是 " ++ (evenOdd n) ++ "！"

prompt :: String -> IO ()
prompt text = do
putStr text
hFlush stdout

main :: IO ()
main = do
prompt "請輸入整數："
input <- getLine
``````

`main` 可以看到，`prompt``getLine``putStrLn`（型態為 `String -> IO ()`），傳回型態都有 `IO`，這表示它們都是輸入輸出相關、具有副作用的函式。

``````isOdd :: Integral a => a -> Bool
isOdd n =
n `mod` 2 == 0

even_odd :: Integral a => a -> String
even_odd n =
if (isOdd n) then "偶數" else "奇數"
``````

## 純綷與不純綷

``````x = 0;
function foo() {
x = x + 1;
return x;
}
``````

Haskell 的函式如果傳回 `IO`，就是使用在告知「你使用了狀態不歸自己管的東西」，如果 `IO` 包含了來自該東西的值，你雖然可以綁定到變數，不過這東西狀態怎麼變動的，有許多你不清楚、無法掌控的細節，你綁定到變數的值，當然也就不是你能掌控！