Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a simple Haskell function reject a Fractional argument expressed as a ratio?

I'm admittedly a Haskell newbie. To explore laziness, I created a function in ghci that returns its second argument:

Prelude> let latter x y = y
latter :: t -> t1 -> t1

I am able to call it with arguments of types Char, [Char], Num, Floating, and Fractional (expressed as decimals):

Prelude> latter 'x' 'y'
'y'
it :: Char

Prelude> latter "foo" "bar"
"bar"
it :: [Char]

Prelude> latter 1 2
2
it :: Num t1 => t1

Prelude> latter pi pi
3.141592653589793
it :: Floating t1 => t1

Prelude> latter 0.5 0.7
0.7
it :: Fractional t1 => t1

Why do I get a horrible error (and what does it mean) when I try applying latter to a Fractional expressed as a ratio:

Prelude> 1/2
0.5
it :: Fractional a => a

Prelude> latter 1/2 1/2

<interactive>:62:1:
    Could not deduce (Num (a0 -> t1 -> t1))
      arising from the ambiguity check for ‘it’
    from the context (Num (a -> t1 -> t1),
                      Num a,
                      Fractional (t1 -> t1))
      bound by the inferred type for ‘it’:
                 (Num (a -> t1 -> t1), Num a, Fractional (t1 -> t1)) => t1 -> t1
      at <interactive>:62:1-14
    The type variable ‘a0’ is ambiguous
    When checking that ‘it’
      has the inferred type ‘forall t1 a.
                             (Num (a -> t1 -> t1), Num a, Fractional (t1 -> t1)) =>
                             t1 -> t1’
    Probable cause: the inferred type is ambiguous
like image 836
Ellen Spertus Avatar asked Feb 01 '15 00:02

Ellen Spertus


People also ask

How are functions defined in Haskell?

The most basic way of defining a function in Haskell is to ``declare'' what it does. For example, we can write: double :: Int -> Int double n = 2*n. Here, the first line specifies the type of the function and the second line tells us how the output of double depends on its input.

How do you negate numbers in Haskell?

Negative literals. Enable negative numeric literals. The literal -123 is, according to Haskell98 and Haskell 2010, two tokens, a unary minus ( - ) and the number 123, and is desugared as negate (fromInteger 123) .

What is returns Haskell?

return is actually just a simple function in Haskell. It does not return something. It wraps a value into a monad. Looks like return is an overloaded function.


1 Answers

Function application in Haskell binds more tightly than anything else. So

latter 1/2 1/2

gets read as

((latter 1) / (2 1)) / 2

Applying 2 to 1 is not such a hot idea, and since latter takes two arguments, latter 1 is actually a function. Dividing a function by something is also not a good idea. You can fix all of these problems using some parentheses:

latter (1/2) (1/2)
like image 101
dfeuer Avatar answered Sep 30 '22 12:09

dfeuer