Namaran

Code daily. Without assist.

2026-08-25

Action.hs

data Action = Action { label :: String, run :: Int -> Int }
  deriving (Eq, Ord, Show)

main :: IO ()
main = print (Action "inc" (+ 1) == Action "inc" (+ 1))

このコードはコンパイルできません。何が問題で、どう直せばよいでしょうか?

Answer

runフィールドの型Int -> Int(関数)にはEqOrdShowのどのインスタンスもありません。関数同士が等しいかを判定したり表示したりする一般的な方法がないためです。derivingは全フィールドの比較・表示が可能であることを前提にするので、この3つとも導出に失敗します。runを比較や表示の対象から外し、labelだけを見る手書きのインスタンスにすれば直ります:

data Action = Action { label :: String, run :: Int -> Int }

instance Eq Action where
  a == b = label a == label b

instance Ord Action where
  compare a b = compare (label a) (label b)

instance Show Action where
  show a = "Action " ++ show (label a)