haskellghciapplicativeliftingderivingvia# Why does this expression have a valid type?

## Numbers

## Ranges

## Putting it all together

Banging around in `ghci`

, I happened to notice that the expression `(*) 1 [1..5]`

apparently has a valid type.

```
:t (*) 1 [1..5]
(*) 1 [1..5] :: (Enum t, Num [t], Num t) => [t]
```

Apparently it is a list with several type constraints, including `Num [t]`

which looks impossible to me, like it should give an error.

How is this the type of the expression? Why does `ghci`

's `:t`

command not give an error here?

Solution

Let's look at how these constraints come to be to explain the type.

In Haskell a literal number is replaced with a call to `fromInteger`

(or `fromRational`

if it has a decimal point or an 'e' in it). This way one can write '1' and have it be float or a double or an int or whatever. The type of `fromInteger`

is

```
fromInteger :: Num a => a
```

So `1`

gets desugared to `fromInteger (1::Integer)`

which has type `Num t => t`

In Haskell the syntax `[a..b]`

is converted into the call `enumFromTo a b`

and the type is `enumFromTo :: Enum a => a -> a -> [a]`

. Putting these together we get

```
[1..5] == enumFromTo (fromInteger 1) (fromInteger 5) :: (Enum a, Num a) => [a]
```

Now the type of `(*)`

is `Num b => b -> b -> b`

so we combine these all together to get:

```
(Num t,
Num a,
Enum a,
Num b,
t~b,
[a]~b) => b
```

Note that `a~b`

means the types `a`

and `b`

are the same. Combining these gives the type

```
(Num a, Enum a, Num [a]) => [a]
```

- Comparing lists in Haskell
- Is there a non-identity monad morphism M ~> M that is monadically natural in M?
- Problem with loading module ‘Distribution.Simple’
- Improving efficiency in Stirling numbers calculation
- Does sequencing an infinite list of IO actions by definition result in a never-ending action? Or is there a way to bail out?
- How to call pgQuery from postgresql-query?
- How to avoid whitespace after a tag (link) in Hamlet templates?
- Understanding type-directed resolution in Haskell with existential types
- Why is seq bad?
- Understanding bind function in Haskell
- How to create route that will trigger on any path in Servant?
- How do I use a global state in WAI middleware?
- nixos 23.11 cabal install mysql-simple problem - "Missing (or bad) C libraries"
- Is there a way to kill all forked threads in a GHCi session without restarting it?
- Why can an invalid list expression such as 2:1 be assigned to a variable, but not printed?
- Iterate over a type level list and call a function based on each type in the list
- How does this solution of Project Euler Problem 27 in the Haskell Wiki work?
- Why `Monad` is required to use `pure`?
- Can't do partial function definitions in GHCi
- recommended way to convert Double -> Float in Haskell
- Haskell profiling understanding cost centre summary for anonymous lambda
- Why is Haskell fully declarative?
- GHC Generating Redundant Core Operations
- Question about Event firing in reflex-frp
- Using Haskell's "Maybe", type declarations
- How can I elegantly invert a Map's keys and values?
- Why there is no output for wrapped IO in Haskell?
- What are the definitions of Weather and Memory in xmobar repo?
- Serializing a Data.Text value to a ByteString without unnecessary \NUL bytes
- Using Haskell with VS Code