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?
We thus see that we make use of two functions here: (&&) :: Bool -> Bool -> Bool , and elem :: (Eq e, Foldable f) => e -> f e -> Bool , we here use e instead of f to avoid "name clashes" with our already defined type variable a .
If you need to figure out what the type of an object is in a Haskell program, I hope this is helpful. Note that if you are in GHCI, you can just put :type before your expression to determine the expression's type, or use :set +t to see the type of every expression in GHCI.
(->) is often called the "function arrow" or "function type constructor", and while it does have some special syntax, there's not that much special about it. It's essentially an infix type operator. Give it two types, and it gives you the type of functions between those types.
(:==) is not a valid symbol for a function or variable identifier in Haskell.
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With