2026-09-21
ClampChecks.hs
module Main where
clamp :: Int -> Int -> Int -> Int
clamp lo hi x
| x < lo = lo
| x > hi = hi
| otherwise = x
check :: String -> Bool -> IO ()
check name ok = putStrLn (name ++ ": " ++ if ok then "pass" else "fail")
-- write this: call `check` for clamp 0 10, covering a value below the
-- range, a value above the range, a value inside the range, and both
-- boundary values (lo and hi themselves).
main :: IO ()
main = do
clamp 0 10を検証するcheckの呼び出しを、範囲外の値2つ・範囲内の値1つ・両端の境界値2つの計5パターンで書いてください。
Reference
main :: IO ()
main = do
check "below" (clamp 0 10 (-5) == 0)
check "above" (clamp 0 10 15 == 10)
check "inside" (clamp 0 10 5 == 5)
check "lower bound" (clamp 0 10 0 == 0)
check "upper bound" (clamp 0 10 10 == 10)
典型的な(範囲内の)値だけを1つ検証しても、clampの本体を丸ごとxを返すだけの実装に差し替えてもそのテストは通ってしまいます。単体テストが本当に検証すべきなのは、実装を間違えやすい境界(lo・hiちょうど)と、その外側の値です。ここでは範囲外を2方向、境界を2点、それに範囲内を1点加えることで、clampの分岐(x < lo・x > hi・otherwise)をひととおりカバーしています。これは参考実装であり、テストケースの名前や順序に唯一の正解はありません。