haskell - 为什么我得到:由于使用“/”而无法推断出(小数 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时无法推断出类型?
解决方案
简短回答:通过指定Num a => a -> a -> a
您声称f
可以处理作为类型类成员的所有 s ,但只能处理作为类型类成员的类型。a
Num
(/)
Fractional
Fractional
是 的“子”类型类Num
。这意味着所有属于 的类型都是 的Fractional
成员Num
,但反之亦然。
通过指定 f 的类型:
f :: Num a => a -> a -> a
你说它f
可以处理作为类型类成员的所有类型。但是,如果您定义为,那是不正确的,因为这意味着应该是 的成员类型。确实有类型。因此,您应该进行更多限制,以便您只能传递具有类型类成员的类型的值:a
Num
f
f x y = x/2 + y + 3
x/2
x
Fractional
(/)
(/) :: Fractional a => a -> a -> a
f
a
a
Fractional
f :: Fractional a => a -> a -> a
f x y = x/2 + y + 3
推荐阅读
- bash - grep 结果:如何格式化输出文件,每行一个结果
- html - 图片不重复
- c# - ASP.NET Core ActionFilter 依赖注入 ObjectDisposedException
- javascript - 从复杂的反应组件中拆分逻辑
- javascript - 交替的项目符号列表颜色
- python - TypeError:只有大小为 1 的数组可以从数据文件转换为 Python 标量
- javascript - 没有为 next.js 组件实现 CSS 样式表
- android - 从 Apache kafka 创建一个 API,以便 Android 应用程序可以从中获取数据
- python - ValueError: int() 以 10 为底的无效文字:'-f'
- ruby-on-rails - Rails 应用程序中的数据和业务逻辑历史