Why can a Num act like a Fractional?

前端 未结 3 1490
一个人的身影
一个人的身影 2020-12-03 23:54

As expected, this works fine:

valFrac :: Fractional a => a
valFrac = undefined

fNum :: Num a => a -> a
fNum a = undefined

resFrac :: Fractional a          


        
3条回答
  •  感情败类
    2020-12-04 00:29

    Works as expected because every Fractional is also a Num.

    That is correct, but it's important to be precise about what this means. It means this: every type in the Fractional class is also in the Num class. It does not mean what someone with an OO or dynamic background might understand: “every value in a Num type is also in a Fractional type”. If this were the case, then your reasoning would make sense: then the Num value bar would be insufficiently general to be used in the foo function.
    ...or actually it wouldn't be, because in an OO language the number hierarchy would work in the other direction – other languages usually allow you to cast any numerical value to a fractional one, but the other direction would in these languages incur round, which reasonably strongly typed ones won't automatically do!

    In Haskell, you need to worry about none of this, because there are never any implicit type conversions. bar and foo work on the exact same type, that this type happens a variable a is secondary. Now, both bar and foo constrain this single type in different ways, but because it's the same type that's constrained you simply get a combination (Num a, Fractional a) of both constraints, which due to Num a => Fractional a is equivalent to Fractional a alone.

提交回复
热议问题