Revamping the numeric classes
Tom Pledger
Tom.Pledger@peace.com
Fri, 9 Feb 2001 17:29:09 +1300
Marcin 'Qrczak' Kowalczyk writes:
| On Thu, 8 Feb 2001, Tom Pledger wrote:
|
| > nice answer: give the numeric literal 10 the range type 10..10, which
| > is defined implicitly and is a subtype of both -128..127 (Int8) and
| > 0..255 (Word8).
|
| What are the inferred types for
| f = map (\x -> x+10)
| g l = l ++ f l
| ? I hope I can use them as [Int] -> [Int].
f, g :: (Subtype a b, Subtype 10..10 b, Num b) => [a] -> [b]
Yes, because of the substitution {Int/a, Int/b}.
| > x + y + z -- as above
| >
| > --> (x + y) + z -- left-associativity of (+)
| >
| > --> realToFrac (x + y) + z -- injection (or treating up) done
| > -- conservatively, i.e. only where needed
|
| What does it mean "where needed"? Type inference does not proceed
| inside-out.
In the expression
(x + y) + z
we know from the explicit type signature (in your question that I was
responding to) that x,y::Int and z::Double. Type inference does not
need to treat x or y up, because it can take the first (+) to be Int
addition. However, it must treat the result (x + y) up to the most
specific supertype which can be added to a Double.
| What about this?
| h f = f (1::Int) == (2::Int)
| Can I apply f
h?
| to a function of type Int->Double?
Yes.
| If no, then it's a pity, because I could inline it (the comparison
| would be done on Doubles). If yes, then what is the inferred type
| for h? Note that Int->Double is not a subtype of Int->Int, so if h
| :: (Int->Int)->Bool, then I can't imagine how h can be applied to
| something :: Int->Double.
There's no explicit type signature for the result of applying f to
(1::Int), so...
h :: (Subtype a b, Subtype Int b, Eq b) => (Int -> a) -> Bool
That can be inferred by following the structure of the term. Function
terms do seem prone to an accumulation of deferred subtype
constraints.
Regards,
Tom