[Haskell筆記]let/in語句
復合函數有助於避免重復。比如,我們有一個求一元二次方程的函數(假定方程有實根):
roots a b c =
((-b + sqrt(b*b - 4*a*c)) / (2*a),
(-b - sqrt(b*b - 4*a*c)) / (2*a))
sqrt(b*b - 4*a*c)重復出現了,使得整個定義顯得很冗長。我們可以利用復合函數來改善這個情況:
delta a b c = sqrt(b*b - 4*a*c) roots' a b u = ((-b + u) / (2*a), (-b - u) / (2*a)) roots a b c = roots' a b (delta a b c)
不過,這種情況,使用let/in語句能使代碼更緊湊:
roots a b c =
let delta = sqrt (b*b - 4*a*c)
in ((-b + delta) / (2*a),
(-b - delta) / (2*a))
使用let/in還有一個好處,就是let語句中定義的符號,如上例的delta,只在in語句後有用。也就是說,定義的delta只在roots函數內部有用。其它函數看不到roots內部定義的delta。當程序比較大時,這種局部綁定可以有效避免符號雜亂的情況。
練習
16.1 下面是一個輸出一元二次函數與x軸交點及頂點坐標的函數,試補全之:
f a b c =
let delta = sqrt (b*b - 4*a*c)
v =
in [(v + delta / (2*a),0),
( ,0),
(v,delta/(-4*a))]
答案
15.1
vol s h = s * h areaCircle r = pi * r ^ 2 areaRect a b = a * b
Prelude> volCircle = vol (areaCircle r) h Prelude> volRect = vol (areaRect a b) h
Leave a Reply