Since fromInteger is part of the Num class, each instance will have its own implementation. None of the two implementations (for Int and Integer ) knows how to make a Float , but they are not called when you use fromInteger (or fromIntegral ) to make a Float ; what for Float instance Num for.
And so on for all other types. There is no place that knows how to turn integers into any type of Num ; this would not be possible, since it would have to support custom Num instances that do not yet exist. Instead, when each individual type is declared an instance of Num , a way should be provided to do this for that particular type (by implementing fromInteger ).
fromInteger will be embedded in an expression that requires it to produce a specific type. He can't know what the type will be? So what is going on?
In fact, knowing which type, which was expected to return from the expression in which the call is embedded, works the same way.
Type checking / output in Haskell works in two “directions” at once. It goes from top to bottom, figuring out what types each expression must have in order to fit into the larger expression in which it is used. And he also goes “from bottom to top”, figuring out what type each expression from the smaller submarine — the expression from which it is built, should have. When he finds a place where they do not match, you get a type error (exactly where the "expected type" and "actual type" you see in the error type codes).
But since the compiler has this upper knowledge ("expected type") for each expression, it is well aware that the fromInteger call fromInteger used where the Float is expected, and therefore use the Float instance for Num in this call.
source share