Haskell:对Num类型类的用法感到困惑 [英] Haskell: confused about uses of Num typeclass

查看:155
本文介绍了Haskell:对Num类型类的用法感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对此工作感到困惑:

f :: Num a => a -> a
f x = x * 42

但这不是:

g :: Num a => a -> a
g x = x * 4.2

我了解到Num包含了实现运算符(+)(-)(*)的所有类型.因此,如果42Int并且4.2Fractional,并且这两种类型都实现了运算符(*),为什么我会为g收到此错误??:

I had understood that Num enclosed all types that implemented operators (+), (-), (*). So, if 42 is an Int and 4.2 is a Fractional, and both types implement the operator (*), why am I getting this error for g?:

Could not deduce (Fractional a) arising from the literal ‘4.2’ 
from the context (Num a)
bound by the type signature for g :: Num a => a -> a
at file.hs:9:6-20
Possible fix:
add (Fractional a) to the context of
the type signature for g :: Num a => a -> a

推荐答案

问题是Num a约束太宽.使用解释器可能会有所帮助:

The problem is that the Num a constraint is too broad. Using the interpreter might help:

Prelude> :type 42
42 :: Num t => t
Prelude> :type 4.2
4.2 :: Fractional t => t

Haskell中的数字文字是多态的,因此正如类型所说,只要类型是NumFractional,这些文字都可以实例化为任何类型.

Numeric literals in Haskell are polymorphic, so as the types are saying, the literals are instantiated as any type as long as the type is a Num or, respectively, a Fractional.

现在查看Num类中(*)函数的类型签名:

Now look at the type signature of the (*) function from the Num class:

Prelude> :type (*)
(*) :: Num a => a -> a -> a

(*)运算符可用于任何Num值,但是两个操作数具有相同的类型.因此,如果要乘以分数类型的值(无论哪种类型,文字4.2都将被实例化为),则另一个操作数也必须是分数的,特别是相同的类型.这就是为什么函数上的Num约束太宽泛的原因:您的函数不能在任何Num类型上运行,而只能在Fractional s上运行,因此编译器说您在函数中缺少Fractional a =>约束.类型签名.

The (*) operator works on any Num value, but the two operands have the same type. So if you are multiplying by a value of Fractional type (whatever type the literal 4.2 will be instantiated into), the other operand must be Fractional as well, and the same type in particular. This is why the Num constraint on your function is too broad: your function cannot work on any Num type, but only on Fractionals, hence the compiler is saying that you are missing a Fractional a => constraint in the type signature.

如果让编译器推断函数的类型,则表示同意:

If you let the compiler inference the type of your function, it will agree:

Prelude> let g x = x * 4.2
Prelude> :type g
g :: Fractional a => a -> a

这篇关于Haskell:对Num类型类的用法感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆