In oop, such as java, we can only downcast a super class into subclass when the type actually is the subclass.
But In haskell, we can simply 'downcast' a type class into any instances of that type class. Such as fromInteger
which return a Num
. From my point of view, it actually is a Int so it cannot be 'downcasted' to Float but it can.
Prelude System.Random> :t fromInteger a
fromInteger a :: Num a => a
Prelude System.Random> fromInteger 12 :: Int
12
Prelude System.Random> fromInteger 12 :: Float
12.0
Another example is to change Random
into Int, Float and even Bool
Prelude System.Random> let (a, g) = random (mkStdGen 12) :: (Int, StdGen)
Prelude System.Random> let (a, g) = random (mkStdGen 12) :: (Double, StdGen)
Prelude System.Random> let (a, g) = random (mkStdGen 12) :: (Bool, StdGen)
We don't know what Random actually is, but we can just 'downcast' it into type of the instance, and it works 100% all the time. I don't understand why it works.