Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prefix form of unary operator in Haskell

In GHCi:

  1. Prelude> (+3) 2
    5
  2. Prelude> (*3) 2
    6
  3. Prelude> (/3) 2
    0.6666666666666666
  4. Prelude> (-3) 2
    No instance for (Num (t -> t1))
    arising from the literal 3' at <interactive>:1:2
    Possible fix: add an instance declaration for (Num (t -> t1))
    In the expression: 3
    In the expression: (- 3) 2
    In the definition of
    it': it = (- 3) 2

How can I correct the last one to make it return -1?

like image 1000
aXqd Avatar asked Aug 04 '10 14:08

aXqd


3 Answers

Haskell's grammar doesn't allow you to use - like that. Use the subtract function instead:

(subtract 3) 2
like image 66
grddev Avatar answered Sep 21 '22 08:09

grddev


As a footnote to grddev's answer, here's the relevant paragraph from the Haskell 98 Report:

The special form -e denotes prefix negation, the only prefix operator in Haskell, and is syntax for negate (e). The binary - operator does not necessarily refer to the definition of - in the Prelude; it may be rebound by the module system. However, unary - will always refer to the negate function defined in the Prelude. There is no link between the local meaning of the - operator and unary negation.

This is something that frustrated me when I first came across it: I couldn't understand why the operators behaved so differently in this context when :info (+) and :info (-) looked basically identical.

You could use subtract, as grddev suggests, or you could just define a new infix operator:

Prelude> let (#) = (-)
Prelude> (# 3) 2
-1

subtract has the advantage of being familiar to other people who might read your code.

like image 26
Travis Brown Avatar answered Sep 20 '22 08:09

Travis Brown


You can do

(-) 3 2

but that will give you 1. To have -1, you need to bind the 3 to the second argument of -, which you can do using

flip (-) 3 2
like image 21
mb14 Avatar answered Sep 19 '22 08:09

mb14