Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mod, div in Haskell

Tags:

haskell

Can someone explain why this doesn't work?

main = do
    let a = 50
    let y = 7
    let area = (a ** y) 
    print (area)   
    print (a `mod` y)

I expected it to print:

781250000000   -- 50 to the 7th power
1              -- remainder of 50/7

But instead I get a series of ambiguous type errors like this:

test.hs:2:13:
    No instance for (Num a0) arising from the literal `50'
    The type variable `a0' is ambiguous
    Possible fix: add a type signature that fixes these type variable(s)
    Note: there are several potential instances:
      instance Num Double -- Defined in `GHC.Float'
      instance Num Float -- Defined in `GHC.Float'
like image 492
Rivalez Avatar asked Dec 11 '15 20:12

Rivalez


People also ask

What does mod do in Haskell?

mod : Returns the modulus of the two numbers. This is similar to the remainder but has different rules when "div" returns a negative number.

What does Div do in Haskell?

div is a prefix operator that correctly performs integer division, throwing away the remainder.

Does Haskell have modulo?

Bookmark this question. Show activity on this post. I'm used to using % to mean "modulo" in other languages. In Haskell, we have to use mod x y or x `mod` y .

What does the operator do in Haskell?

Haskell provides special syntax to support infix notation. An operator is a function that can be applied using infix syntax (Section 3.4), or partially applied using a section (Section 3.5).


1 Answers

Simple; take a look at the types of (**) and mod:

Prelude> :t (**)
(**) :: Floating a => a -> a -> a
Prelude> :t mod
mod :: Integral a => a -> a -> a

It is a rare numeric type that has both the characteristics of an integer and the characteristics of a floating-point number. You have a couple of choices for dealing with this:

  1. Use an exponentiation operation that handles integer-like numbers well. For example, (^) :: (Integral b, Num a) => a -> b -> a.
  2. Use a modulus operation that handles floating-point numbers well. For example, mod' :: Real a => a -> a -> a.
  3. Explicitly convert to a floating-point type with realToFrac :: (Real a, Fractional b) => a -> b before calling (**).
  4. Explicitly convert to an integer-like type with floor :: (RealFrac a, Integral b) => a -> b (or another rounding function) before calling mod.
like image 121
Daniel Wagner Avatar answered Sep 28 '22 02:09

Daniel Wagner