Sergio
Sergio

Reputation: 13

Haskell Making sense of types

I have been experimenting with Haskell, and trying out some simple list comprehensions. I just stumbled upon what I can only describe as strange behavior using the ghci.

Here is my output:

GHCi, version 8.10.2: https://www.haskell.org/ghc/  :? for help
Prelude> l = [(b `div` 3, b) | b<-[1..1000], b `mod` 3 == 0]
Prelude> :t l
l :: Integral b => [(b, b)]
Prelude> take 50 l
[(1,3),(2,6),(3,9),(4,12),(5,15),(6,18),(7,21),(8,24),(9,27),(10,30),(11,33),(12,36),(13,39),(14,42),(15,45),(16,48),(17,51),(18,54),(19,57),(20,60),(21,63),(22,66),(23,69),(24,72),(25,75),(26,78),(27,81),(28,84),(29,87),(30,90),(31,93),(32,96),(33,99),(34,102),(35,105),(36,108),(37,111),(38,114),(39,117),(40,120),(41,123),(42,126),(43,129),(44,132),(45,135),(46,138),(47,141),(48,144),(49,147),(50,150)]
Prelude> 
Prelude> l = [('a', b) | b<-[1..1000], b `mod` 3 == 0]
Prelude> :t l
l :: Integral b => [(Char, b)]
Prelude> take 50 l
[('a',3),('a',6),('a',9),('a',12),('a',15),('a',18),('a',21),('a',24),('a',27),('a',30),('a',33),('a',36),('a',39),('a',42),('a',45),('a',48),('a',51),('a',54),('a',57),('a',60),('a',63),('a',66),('a',69),('a',72),('a',75),('a',78),('a',81),('a',84),('a',87),('a',90),('a',93),('a',96),('a',99),('a',102),('a',105),('a',108),('a',111),('a',114),('a',117),('a',120),('a',123),('a',126),('a',129),('a',132),('a',135),('a',138),('a',141),('a',144),('a',147),('a',150)]
Prelude> 
Prelude> l = [(b/3, b) | b<-[1..1000], b `mod` 3 == 0]
Prelude> :t l
l :: (Integral b, Fractional b) => [(b, b)]
Prelude> take 50 l

<interactive>:11:1: error:
    • Ambiguous type variable ‘b0’ arising from a use of ‘print’
      prevents the constraint ‘(Show b0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘b0’ should be.
      These potential instances exist:
        instance Show Ordering -- Defined in ‘GHC.Show’
        instance Show Integer -- Defined in ‘GHC.Show’
        instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
        ...plus 22 others
        ...plus 13 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In a stmt of an interactive GHCi command: print it
Prelude> 

The first two definitions of 'l' are straight forward, and exactly what i would expect. I do not understand the third one. Specifically, why the type is not defined as:

l :: (Fractional a, Integral b) => [(a, b)]

If anybody could resolve my confusion, i would greatly appreciate it.

Upvotes: 1

Views: 72

Answers (1)

Ari Fordsham
Ari Fordsham

Reputation: 2515

As @Willem Van Onsem noted, the two members of the tupes in l are the result of (/), whose type is Fractional a => a -> a -> a, because it requires both it's operands to be the same type, which also determines the result.

Upvotes: 1

Related Questions