Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the unary minus operator problematic in this expression: (- 2) 1? [duplicate]

All of the following expressions get evaluated without mishap:

(+2) 1 -- 3
(*2) 1 -- 2
((-)2) 1 -- 1
(2-) 1 -- 1   
(/2) 1 -- 0.5
(2/) 1 -- 2.0

but not this one:

(-2) 1 -- the inferred type is ambiguous

GHC throws some error about the inferred type being ambiguous. Why?

like image 755
sof Avatar asked Mar 06 '15 00:03

sof


People also ask

What is a unary minus operator?

The - (unary minus) operator negates the value of the operand. The operand can have any arithmetic type. The result is not an lvalue. For example, if quality has the value 100 , -quality has the value -100 . The result has the same type as the operand after integral promotion.

What affect does the unary operator have when applied to a numeric expression?

Unary - changes the sign of a numeric expression to the right of the operator. Unary + has no effect on an expression; it is included for completeness and because some programmers like to use it to emphasize that a number is positive.

What is the use of unary operator?

The unary operators require only one operand; they perform various operations such as incrementing/decrementing a value by one, negating an expression, or inverting the value of a boolean. The increment/decrement operators can be applied before (prefix) or after (postfix) the operand.


1 Answers

The first six parenthesised expressions are sections, i.e. functions that take one argument and "put it on the missing side of the infix operator" (see this haskell.org wiki). In contrast, (-2) is, not a function, but a number (negative 2):

λ> :t (-2)
(-2) :: Num a => a

If you write

λ> (-2) 1

it looks like you're trying to apply (-2) (a number) to 1 (which is not possible), and GHCi rightfully complains:

Could not deduce (Num (a0 -> t))
  arising from the ambiguity check for ‘it’
from the context (Num (a -> t), Num a)
  bound by the inferred type for ‘it’: (Num (a -> t), Num a) => t
  at <interactive>:3:1-6
The type variable ‘a0’ is ambiguous
When checking that ‘it’
  has the inferred type ‘forall a t. (Num (a -> t), Num a) => t’
Probable cause: the inferred type is ambiguous

If you want a function that subtracts 2 from another number, you can use

(subtract 2)

Compare its type,

λ> :t (subtract 2)
(subtract 2) :: Num a => a -> a

to that of (-2) (see above).


Terminology addendum (after OP's edit)

Parenthesizing the minus operator turns it into a normal (prefix) function that takes two arguments; therefore ((-) 2) is not a section, but a partially applied function.

like image 58
jub0bs Avatar answered Sep 22 '22 02:09

jub0bs