Namaran

Code daily. Without assist.

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])