I have written the following Haskell code to return the primary and secondary diagonal of [[Int]]
getDiagonal' :: [[Int]] -> Int -> (Int -> Int) -> [Int]
getDiagonal' [] _ _ = []
getDiagonal' (x:xs) i fn = i' : getDiagonal' xs (fn i) fn
where i' = head $ drop i x
getPrimaryDiagonal :: [[Int]] -> [Int]
getPrimaryDiagonal x = getDiagonal' x 0 (+1)
getSecondaryDiagonal :: [[Int]] -> [Int]
getSecondaryDiagonal x = getDiagonal' x ((length x) - 1) (+(-1))
However, I would have thought that the final line could be the following, using (-)
the same way as (+)
getSecondaryDiagonal x = getDiagonal' x ((length x) - 1) (-1)
However, that does not work, when I do that I get
Main.hs:27:59: error:
• No instance for (Num (Int -> Int))
arising from a use of syntactic negation
(maybe you haven't applied a function to enough arguments?)
• In the third argument of ‘getDiagonal'’, namely ‘(- 1)’
In the expression: getDiagonal' x ((length x) - 1) (- 1)
In an equation for ‘getSecondaryDiagonal’:
getSecondaryDiagonal x = getDiagonal' x ((length x) - 1) (- 1)
Why does (-)
produce that error?
(-1)
is interpreted as negative one, it is, as far as I know, the only exception that is made for operators that are non-binary. (-1)
is thus not a function that subtracts one away.
You can make use of subtract :: Num a => a -> a -> a
for this:
getSecondaryDiagonal x = getDiagonal' x ((length x) - 1) (subtract 1)
or you can use flip :: (a -> b -> c) -> b -> a -> c
which is how subtract
is implemented:
getSecondaryDiagonal x = getDiagonal' x ((length x) - 1) (flip (-) 1)