Andrew De Andrade
Andrew De Andrade

Reputation: 3616

How do I get the type signature of the range function in Haskell?

Many functions in Haskell made up of special characters in Haskell are infix functions. These include *, +, ==, /, etc. To get the type signatures of such functions you put the function in parentheses and execute :t, like so:

GHCi> :t (==)
(==) :: Eq a => a -> a -> Bool

I wanted to try and get the type signature of the range function, [a..a], but it seems that this function is infix, but can only be used within a list []. I tried all the following, but none worked:

GHCi> :t (..)
<interactive>:1:2: parse error on input `..'
GHCi> :t ([..])
<interactive>:1:3: parse error on input `..'
GHCi> :t [..]
<interactive>:1:2: parse error on input `..'
GHCi> :t ..
<interactive>:1:1: parse error on input `..'

Does anyone know how to get the type signature of the range function?

Upvotes: 5

Views: 238

Answers (2)

Tikhon Jelvis
Tikhon Jelvis

Reputation: 68172

The .. is not a function, it's actually syntax sugar. It gets translated to one of several functions: enumFrom, enumFromThen, enumFromTo or enumFromThenTo.

It can't be a normal function because it has four forms that work in different ways. That is, all four of these are valid:

[1..]     -- enumFrom 1
[1,2..]   -- enumFromThen 1 2
[1..10]   -- enumFromTo 1 10
[1,2..10] -- enumFromThenTo 1 2 10

These forms use the four functions I mentioned respectively.

If it was just a normal operator, 1.. would give you a partially applied function; instead, it produces a list. Moreover, for a normal function, the [1,2..10] notation would be parsed as [1,(2..10)] where in reality it all gets turned into a single function taking all three numbers as arguments.

These functions are all part of the Enum class, so the .. notation works for any type that is part of it. For example, you could write [False ..] and get the list [False, True]. (Unfortunately, due to current parsing ambiguities, you can't write [False..] because it then assumes False is a module.)

Upvotes: 13

huon
huon

Reputation: 102236

Try using a lambda.

> :t \x y -> [x..y]

The notation is just syntactic sugar for enumFrom and enumFromTo so it doesn't really have a conventional type.

Upvotes: 8

Related Questions