Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

haskell type signature for integers

Tags:

haskell

Say I want to write a function to decide whether a given integer number is prime, which type signature should I use?

  isPrime :: Int -> Bool

or

  isPrime :: (Integral a) => a -> Bool

What's the difference? Is there a particular reason to choose one over the other?
If so, in which situations should I use the two respectively?

like image 364
manuzhang Avatar asked Jan 13 '12 04:01

manuzhang


People also ask

What are type signatures in Haskell?

From HaskellWiki. A type signature is a line like. inc :: Num a => a -> a. that tells, what is the type of a variable. In the example inc is the variable, Num a => is the context and a -> a is its type, namely a function type with the kind * -> * .

Which function is used to find type signature in Haskell?

Since the type of elem y z is Bool , this matches with the function (&&) x , and thus the type of (&&) x (elem y z) is thus Bool .

What does A -> B mean in Haskell?

a -> b Bool means... forall (a :: *) (b :: * -> *). a -> b Bool. b is therefore a type constructor taking a single type argument. Examples of single-argument type constructors abound: Maybe , [] , IO are all examples of things which you could use to instantiate b .

What is integer Haskell?

Haskell has two integral types, namely Int and Integer . Int is the type of limited-precision integers; this means that there is a smallest integer of type Int , namely minBound , and a greatest integer of type Int , namely maxBound .


1 Answers

The type Int -> Bool means that your function operates on values of type Int, which are size-limited integers (the maximum size being, I believe, machine-dependent).

The type (Integral a) => a -> Bool means that your function operates on values of any type that has an instance of the Integral type class--i.e., types that behave like integers in a particular way. The main reason to chose this over a concrete type is to create a more general-purpose function.

Generic forms using Integral tend to be most useful when you need to work with integer-like types in other contexts--a good example being places where the standard library fails to do so, e.g. functions like replicate :: Int -> a -> [a]. Code that operates on some specific integer-like type for its own purposes that wants to use that type with replicate therefore needs to convert to Int first, or import genericReplicate from Data.List.

What you might want to consider in your case is instead the type Integer, which represents integers of arbitrary size. Since your main goal is the calculation, there's less value to supporting arbitrary integral types.

If memory serves me, the only instances of Integral in the standard library are Int and Integer anyhow. (EDIT: As hammar reminds me in the comments, there are also instances for fixed-size types in Data.Int and Data.Word. There are also foreign types like CInt but I was disregarding those intentionally.)

like image 52
C. A. McCann Avatar answered Nov 10 '22 09:11

C. A. McCann