2026-09-20
DecrementAll.hs
decrementAll :: [Int] -> [Int]
decrementAll = map (- 1)
main :: IO ()
main = print (decrementAll [1, 2, 3])
(+ 3)が\x -> x + 3になるのと同じように、(- 1)で「1を引く」無名関数を作ったつもりですが、このコードはコンパイルできません。何が問題で、どう直せばよいでしょうか?
Answer
演算子セクション(op x)は、+や*など他のほとんどの演算子では期待どおり無名関数になりますが、-だけは特別扱いされています。Haskellの文法では-が単項のマイナス(符号反転)にも使われるため、(- 1)は常に「1を単項マイナスで反転した値」、つまりただの数値-1として解釈され、セクションにはなりません。そのためmap (- 1) xsは「関数ではなく数値をmapの第1引数に渡している」型エラーになり、コンパイルが通りません。この曖昧さを避けるため、Haskellは「1を引く」というセクションのための専用関数subtractを標準ライブラリに用意しています。(- 1)の代わりにsubtract 1を使えば、意図どおり「引数から1を引く」無名関数として振る舞います:
decrementAll :: [Int] -> [Int]
decrementAll = map (subtract 1)
main :: IO ()
main = print (decrementAll [1, 2, 3])