3日目 数値の型など

1.3.3

search を書いてみる。

search :: (Fractional a, Ord a) => (a -> a) -> a -> a -> a
search f neg pos = let mid = average neg pos
                   in if closeEnough neg pos
                      then mid
                      else case signum (f mid) of
                               1  -> search f neg mid
                               -1 -> search f mid pos
                               0  -> mid

average ::Fractional a => a -> a -> a
average x y = (x + y) / 2

closeEnough :: (Fractional a, Ord a) => a -> a -> Bool
closeEnough x y = abs (x - y) < 0.001

改行やインデントの具合は hugs のコードを見てそれっぽくしました。型は Float と決め打ちしないでやってみたんですが、ちゃんとはわかってない。まずべた書きした数値リテラルがどうなるかわからないので、report で調べると
6.4.1 Numeric Literals
整数リテラルは Num クラスの fromInteger、小数は Fractional クラスの fromRational で変換される。なので average と closeEnough はこれでいい。 あとわからないのは signum が (-1, 0, 1) のどれかを返すことを期待しているところで、report によると実数ではそうだと書いてある。search の型は (Fractional a, Ord a) じゃなくて (Fractional a, Real a) の方がいいのかも。数学の話になってくると手に負えないのでまあいいや。