You can read about these subjects in Learn You a Haskell, chapters 1-4.
A range can be infinite. For example, here is a list of integers from 1 to ∞:
> ints = [1..]
The built-in function take
will take
only the first N elements of a list for a given N. It is convenient
for looking at the first values of an infinite list:
> take 10 ints [1,2,3,4,5,6,7,8,9,10]
As an alternative to Haskell's range syntax, we can write a function to generate an infinite list of numbers:
intsFrom :: Integer -> [Integer] intsFrom x = x : intsFrom (x + 1)
For example:
> take 10 (intsFrom 1) [1,2,3,4,5,6,7,8,9,10]
We can use a similar technique to generate an infinite list of Fibonacci numbers:
fibsFrom :: Integer -> Integer -> [Integer] fibsFrom i j = i : fibsFrom j (i + j)
Let's try it:
> take 15 (fibsFrom 1 1) [1,1,2,3,5,8,13,21,34,55,89,144,233,377,610]
Notice that in each of the examples above, our function produced one list element, then called itself recursively to generate the rest of the list.
We can even define an infinite list using a recursive variable definition:
> ones = 1 : ones > take 10 ones [1,1,1,1,1,1,1,1,1,1]
In Haskell, even numeric literals are polymorphic:
> :t 2 2 :: Num a => a > :t 3.5 3.5 :: Fractional a => a
We see that 2 may have any type that's an instance of the Num
type class (e.g. Int
, Integer
,
Float
, Double
).
Similarly, 3.5 may have any type that's an instance of Fractional
(e.g. Float
, Double
).
We may choose any compatible type that we like:
> 2 :: Integer 2 > 3.5 :: Float 3.5
Even when we combine literals using operators, the result may still be polymorphic:
> :t (2 + 2) (2 + 2) :: Num a => a > :t (2 + 3.5) (2 + 3.5) :: Fractional a => a
However in some situations Haskell must choose a type. For example, suppose that we actually perform the addition:
> 2 + 2 4 > 2 + 3.5 5.5
What type did Haskell use in the calculation? Its rule is that if it
must resolve an ambiguous numeric type, it will use the first of
these types that is possible: Integer
,
Double
. Thus, the first addition above
was performed using values of type Integer
,
and the second used type Double
.