Namaran

Code daily. Without assist.

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を返すだけの実装に差し替えてもそのテストは通ってしまいます。単体テストが本当に検証すべきなのは、実装を間違えやすい境界(lohiちょうど)と、その外側の値です。ここでは範囲外を2方向、境界を2点、それに範囲内を1点加えることで、clampの分岐(x < lox > hiotherwise)をひととおりカバーしています。これは参考実装であり、テストケースの名前や順序に唯一の正解はありません。