Chris
Chris

Reputation: 1128

Defining functions: type constraints with more than one variable

Working with this function:

getK x y
    | y < 1 = error "Index can not be less than 1!"
    | y > length x = error "Index greater than array length"
    | otherwise    = x !! (y-1)

If I don't define a type, GHC is fine with it.

*Main> :info getK
 getK :: [a] -> Int -> a    -- Defined at main.hs:7:1

But suppose I write the type constraint as:

getK :: (Int b) => [a] -> b -> a 

As far as I can tell, the above is what GHC inferred. But no, it produces the following error:

main.hs:6:10:
`Int' is applied to too many type arguments
In the type signature for `getK': getK :: Int b => [a] -> b -> a
Failed, modules loaded: none.

My immediate reaction was that there must have been a problem by my not assigning a type to 'a'. (Although there shouldn't have been because GHC recognizes that 'a' can be any type. So I then tried:

getK :: (Num a, Ord a, Int b) => [a] -> b -> a 

Another error...

main.hs:6:24:
`Int' is applied to too many type arguments
In the type signature for `getK':
  getK :: (Num a, Ord a, Int b) => [a] -> b -> a 

Please help me understand the behavior here.

Upvotes: 0

Views: 125

Answers (1)

David Young
David Young

Reputation: 10783

Int is a type, not a type class. Only type classes like Num and Ord can be used as type constraints. This is how your signature would be written:

getK :: [a] -> Int -> a

GHCI has a :info command (this can be abbreviated :i) that will tell you about types and type classes and compare what it has to say about Int vs what it says about Num:

λ> :i Int
data Int = GHC.Types.I# GHC.Prim.Int#   -- Defined in ‘GHC.Types’
instance Bounded Int -- Defined in ‘GHC.Enum’
instance Enum Int -- Defined in ‘GHC.Enum’
instance Eq Int -- Defined in ‘GHC.Classes’
instance Integral Int -- Defined in ‘GHC.Real’
instance Num Int -- Defined in ‘GHC.Num’
instance Ord Int -- Defined in ‘GHC.Classes’
instance Read Int -- Defined in ‘GHC.Read’
instance Real Int -- Defined in ‘GHC.Real’
instance Show Int -- Defined in ‘GHC.Show’
λ> 
λ> 
λ> :i Num
class Num a where
  (+) :: a -> a -> a
  (*) :: a -> a -> a
  (-) :: a -> a -> a
  negate :: a -> a
  abs :: a -> a
  signum :: a -> a
  fromInteger :: Integer -> a
    -- Defined in ‘GHC.Num’
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Int -- Defined in ‘GHC.Num’
instance Num Float -- Defined in ‘GHC.Float’
instance Num Double -- Defined in ‘GHC.Float’

Upvotes: 2

Related Questions