首页 > 解决方案 > 为什么我得到:由于使用“/”而无法推断出(小数 a)?

问题描述

我在.hs文件中有以下代码

module TypeInference1 where
f :: Num a => a -> a -> a
f x y = x + y + 3

然后如果我检查f的类型,我会得到以下结果,这没关系:

*TypeInference1> :t f
f :: Num a => a -> a -> a

如果我将一个小数类型的参数传递给f并检查它的类型,我将获得:

*TypeInference1> :t f 1.0
f 1.0 :: Fractional a => a -> a

但另一方面,如果我通过对其一个参数设置除法运算来更改f,如下所示: f x y = x/2 + y + 3

我收到以下错误:

5-typeInference1.hs:4:9: error:
    • Could not deduce (Fractional a) arising from a use of ‘/’
      from the context: Num a
        bound by the type signature for:
                   f :: forall a. Num a => a -> a -> a
        at 5-typeInference1.hs:3:1-25
      Possible fix:
        add (Fractional a) to the context of
          the type signature for:
            f :: forall a. Num a => a -> a -> a
    • In the first argument of ‘(+)’, namely ‘x / 2’
      In the first argument of ‘(+)’, namely ‘x / 2 + y’
      In the expression: x / 2 + y + 3

为什么会发生这种情况以及为什么当我像上面那样更改函数f时无法推断出类型?

标签: haskell

解决方案


简短回答:通过指定Num a => a -> a -> a您声称f可以处理作为类型类成员的所有 s ,但只能处理作为类型类成员的类型。aNum(/)Fractional

Fractional是 的“子”类型类Num。这意味着所有属于 的类型都是 的Fractional成员Num,但反之亦然

通过指定 f 的类型:

f :: Num a => a -> a -> a

你说它f可以处理作为类型类成员的所有类型。但是,如果您定义为,那是不正确的,因为这意味着应该是 的成员类型。确实有类型。因此,您应该进行更多限制,以便您只能传递具有类型类成员的类型的值:aNumff x y = x/2 + y + 3x/2xFractional(/)(/) :: Fractional a => a -> a -> afaaFractional

f :: Fractional a => a -> a -> a
f x y = x/2 + y + 3

推荐阅读