Namaran

Code daily. Without assist.

2026-09-21

SortedChecks.hs

module Main where

isSorted :: [Int] -> Bool
isSorted xs = and (zipWith (<=) xs (drop 1 xs))

check :: String -> Bool -> Bool -> IO ()
check name expected actual =
  putStrLn (name ++ ": " ++ if expected == actual then "pass" else "fail")

main :: IO ()
main = do
  check "empty" True (isSorted [])
  check "single" True (isSorted [5])
  check "sorted" True (isSorted [1, 2, 3])
  check "unsorted" False (isSorted [3, 1, 2])
  check "duplicates" True (isSorted [1, 1, 2])

このコードは何を出力するでしょうか?

Answer

empty: passsingle: passsorted: passunsorted: passduplicates: passの5行(すべてpass)。isSortedは隣接する要素の組をすべて<=で比較していますが、zipWithは短い方のリストの長さに合わせて止まるため、xsが空や1要素の場合はdrop 1 xsとの組が1つも作れず、比較結果は空リスト[]になります。and []はHaskellの仕様上True(空リストに対する論理積は真)なので、emptysingleのケースは特別扱いのコードを書かなくても正しくTrueになります。この単体テストが検証しているのは「典型的な入力で正しく動くか」だけでなく、境界(空リスト・要素1個)や、値が重複する場合(厳密な<ではなく<=で判定できているか)といった、実装を間違えやすい条件です。