不同Num类型的不等式

per*_*nto 1 haskell

如何使用以下代码来比较不同的数字类型?

foo::(Num a) => (Num b) => a -> b -> Bool
foo a b = (a == b)
Run Code Online (Sandbox Code Playgroud)

我从上下文中得出关于推导(a~b)的错误(Num a,Num b)

Dan*_*her 8

首先,你的类型签名在语法上是错误的(根据我对报告中无上下文语法的解读,尽管GHC接受它),它应该是

foo::(Num a, Num b) => a -> b -> Bool
Run Code Online (Sandbox Code Playgroud)

关于这个问题,你不能这样做,(<)有类型Ord a => a -> a -> Bool,所以两个参数必须具有相同的类型.

如果有更强的限制Num,你就可以拥有

bar :: (Real a, Real b) => a -> b -> Bool
bar a b = toRational a < toRational b
Run Code Online (Sandbox Code Playgroud)

您需要能够将两个参数转换为相同的目标类型(通过有意义的转换)来比较这些值.对于类中的Real类型,toRational提供对公共目标类型的这种转换(toRational如果起始类型是浮点类型,那么对于NaN和无穷大不起作用的警告).toInteger对于Integral约束会达到相同的效果.

只有一个Num约束,没有这样的共同目标类型.

为满足您的特殊需求,您可以选择目标类型并定义

class Convertible a where
    toTarget :: a -> Target
Run Code Online (Sandbox Code Playgroud)

如果RealIntegral不是可行的约束.