Sunday 4 August 2013

Haskell 入門! (4)

Haskell 入門企画第四回.
とうとう関数定義するぜ!

en.wikibooks の Haskell から.CC-BY-SA で配布.

Functions

複数の円の面積を求めたい場合,
-- twoareas.hs
r = 5
area = pi*r^2
r2 = 3
area2 = pi*r2^2
…なんてやるのはあまりにひどい.ここで function の出番です.
function は argument value (or parameter) をとって,結果の値を与えるもの.
数学の函数と (Haskell でいう関数は!)一緒で,一連のタスクをまとめたものとは雰囲気が違う.
書き方はシンプル,variable 定義するのと同じノリで,左辺に argument を書いておく.
area r = pi * r^2 -- 数式でいうと A(r) = \pi * r^2
関数名,space あけて argument(s) の順に書いて括弧は使わない.
def みたいな特別な syntax はなく, r = 5 って定義したのと同じノリで,この書き方で定義する.

さてではこれを call してみよう.とりあえずは ghci で読み込んで
*Main> area 3
28.274333882308138
*Main> area 5
78.53981633974483
*Main> :t area
area :: Floating a => a -> a
:t のところ,まだ出てきてませんが type のことをやれば意味がわかるので少しお待ちを.
関数の引数を示すのに括弧で括ることはしませんが,expressions (値を与えるあらゆる code) を纏めて一緒に評価させるときには
area (5+3)
みたいにくくる.
この場合は最初に 5+3 (もちろん 8 )を計算して,その area を計算します.一方
area 5 + 3
ではまず area 5 を計算して,それに 3 を足すことになります.
これは掛け算が足し算より順位が高いのとおなじように, function call が先に行われるということ.
では
area 5 * 3
area 1 ^ 3
はそれぞれどうなるでしょう.(演習課題?)
せっかくだから,もうちょっと関数を書いてみよう.
double x = 2 * x
quadruple x = double(double x)
square x = x * x
half x = x / 2
うむ.

Evaluation

GHCi に expression を打ち込んだ時に何が起こるのか.
Enter 押したら ghci は打ち込んだ expression を 評価 --evaluate-- します.
これはつまり, 関数を定義で置き換え,結果を計算して,最後に値がひとつだけ残るまでそれをやる,ということ.
さっきの area 5 でやってみましょうか.
    area 5
=>   {- 定義の area r = を 右辺の pi * r^2 で置き換え-}
    pi * 5^2
=> {- pi を数値に置き換え-}
    3.141592653589793 * 5^2
=> {- 指数(^)を適用 -}
    3.141592653589793 * 25
=> {- 掛け算 -}
    78.53981633974483
あ,別に => は Haskell さん的なアレじゃないよ.
練習問題.
  • 少し前の quadruple 5 は ghci さんにどう評価されるか.再掲すると
    double x = 2 * x
    quadruple x  = double(double x)
    
  • 引数の半分から 12 を引く関数書いてみよう.

Multiple parameters

もちろん引数は一つとは限らないよー.書き方は前と一緒でここでも括弧は使わない.
縦と横与えられて長方形の面積:
areaRect l w = l * w

*Main> areaRect 5 10
50
直角三角形の面積求めるぜ
areaRightTriangle b h = (b * h) /2
使うときはこんなかんじに引数同士をスペースで区切る.
だから(?)括弧使って評価の順番を指定しないと誤解が生じることもあるわけですねー.
quadruple x = double double x
と,書くとします.実は関数も他の関数の引数になれちゃうので誤解が起きる.
関数を関数に投げる話はまた後でするとして,とりあえずちゃんと誤解を解くために
quadruple x = double (double x)
とすればめでたく思っているとおりに通る.
ついでに一応確認しとくと引数の順番は書いてあるままです.
subtract x y = x - y
なら subtract 10 5 5 , subtract 5 10 -5.
なおいままで何の気無しに使ってた + とかも関数で, (+) と書くと本来の関数としての syntax で使えます.
Prelude> (+) 3 2 
5
演習.
  • 直方体の体積出す関数書いてみよう.
  • Giza のピラミッドって大体どのくらいの数の石でできてるだろう? GHCi さんの助けを借りて計算してみよう.

関数使って関数作るのももちろんできるよ
長方形と正方形の面積求めるもの
areaRect l w = l * w
areaSquare s = areaRect s s
こういうのできるの,後々わかってくるけど超便利.
演習.
  • 円柱の体積求める関数書いてみよう.


No comments:

Post a Comment