
On 27.05.2016 20:42, Jeffrey Brown wrote:
Without a type signature, all GHCI knows:
Prelude> :t read "2" read "2" :: Read a => a
is that it should return some kind of Read -- that is, something that can be from a string. GHCI is not being asked to return any (concrete) type.
If that were true (which it would be without extensions), the code would fail to compile rather than throwing a runtime exception. But as your parent post stated, GHCi enables ExtendedDefaultRules by default, defaulting to (). Note that this means that `read "()"` works without any type annotations and produces ().
You don't necessarily have to provide a type signature, though, if it can be inferred from context:
Prelude> floor $ read "2" 2 Prelude> :t floor floor :: (Integral b, RealFrac a) => a -> b Prelude> :t floor $ read "2" floor $ read "2" :: Integral b => b
Note that GHCI in this case still does not know exactly the type of (floor $ read "2"), but thanks to the type of floor, it knows enough to proceed.
That's not accurate. If it did not know which numeric type to use, it would not be able to pick which overload of read to use (it's not like all RealFracs share the same implementation of read), so it wouldn't be able to produce a result. So again defaulting rules apply (this time even without extensions) and the `read "2"` in `floor $ read "2"` produces a Double (unless you declare a different default type).