Why does this function require a list of integers?
Prelude> :t \xs->[(map $ uncurry(*)) (zip xs [1..n]) | n<-[1..(length xs)]]
\xs->[(map $ uncurry(*)) (zip xs [1..n]) | n<-[1..(length xs)]]
:: [Int] -> [[Int]]
When I replace length xs
with a fixed value, the type changes and isn’t that strict anymore:
Prelude> :t \xs->[(map $ uncurry(*)) (zip xs [1..n]) | n<-[1..100]]
\xs->[(map $ uncurry(*)) (zip xs [1..n]) | n<-[1..100]]
:: (Num b, Enum b) => [b] -> [[b]]
My compiler is
$ ghci --version
The Glorious Glasgow Haskell Compilation System, version 8.8.4
CodePudding user response:
length
has type Foldable t => t a -> Int
, which means length xs
is specifically an Int
value. That makes [1..(length xs)]
be of type [Int]
, etc.
100
, on the other hand, is not an Int
literal, but a polymorphic literal of type Num a => a
. That makes [1..100]
have type Num a => [a]
, etc.
Which is to say, length
is the only thing that's forcing a concrete type like Int
in the final type. Replace that with the more general 100
, and the final type is more general as well.