Haskell 哈斯凯尔:没有任何实例出现

Haskell 哈斯凯尔:没有任何实例出现,haskell,types,Haskell,Types,从Haskell开始,我经常遇到类型问题(以及GHC中不太有用的错误消息)。我定义了以下功能: ghci>让f x=楼层x==x ghci>:t f f::(积分a,实分数a)=>a->Bool 它成功了,但调用起来很困难: ghci>设a=1.1 ghci>fa :296:1: 没有因使用“f”而产生的(二重积分)实例 可能的修复方法:添加(整数双精度)的实例声明 在表达式中:fa 在‘it’的方程式中:it=fa ghci>设b=2 ghci>FB :298:1: 没有因使用“f”而产生的

从Haskell开始,我经常遇到类型问题(以及GHC中不太有用的错误消息)。我定义了以下功能:

ghci>让f x=楼层x==x
ghci>:t f
f::(积分a,实分数a)=>a->Bool
它成功了,但调用起来很困难:

ghci>设a=1.1
ghci>fa
:296:1:
没有因使用“f”而产生的(二重积分)实例
可能的修复方法:添加(整数双精度)的实例声明
在表达式中:fa
在‘it’的方程式中:it=fa
ghci>设b=2
ghci>FB
:298:1:
没有因使用“f”而产生的(RealFrac Integer)实例
可能的修复方法:为(RealFrac Integer)添加实例声明
在表达式中:fb
在‘it’的方程式中:it=fb
如何正确定义函数?

Haskell不会在不同的数字类型之间进行任何自动强制,因此,如果比较
x==y
,则
x
y
必须具有完全相同的类型(例如,两者都是int或两者都是float)

现在,如果您查看
地板的类型,它是

floor :: (Integral b, RealFrac a) => a -> b
这意味着您只能对分数类型调用它,而结果类型必须是整数类型

当您在
f
内部调用
f1.1
时,您将进行比较

floor 1.1 == 1.1
但是现在您遇到了一个问题,因为
floor
只能返回整数类型,为了进行比较,结果必须具有与
1.1
相同的类型,这肯定不是整数

您需要将
f
定义为

let f x = fromIntegral (floor x) == x
调用将整数下限值强制转换回一个分数值,以便与原始的
x

Haskell不会在不同的数字类型之间进行任何自动强制,因此如果比较
x==y
,则
x
y
必须具有完全相同的类型(例如,两者都是整数或浮动)

现在,如果您查看
地板的类型,它是

floor :: (Integral b, RealFrac a) => a -> b
这意味着您只能对分数类型调用它,而结果类型必须是整数类型

当您在
f
内部调用
f1.1
时,您将进行比较

floor 1.1 == 1.1
但是现在您遇到了一个问题,因为
floor
只能返回整数类型,为了进行比较,结果必须具有与
1.1
相同的类型,这肯定不是整数

您需要将
f
定义为

let f x = fromIntegral (floor x) == x

调用会强制将整数下限值转换回分数值,以便与原始的
x

进行比较。请确保在定义函数时始终使用类型签名,以便编译器准确地知道您在说什么。实际上,添加类型签名通常会显著改善GHC错误消息。请确保您在定义函数时总是使用类型签名,这样编译器就可以准确地知道您在说什么。事实上,添加类型签名通常会显著地改善GHC错误消息。有点离题:我想知道在例如
Double->Double
转换的情况下,这是否会得到优化。我的意思是,转换
似乎很愚蠢>1e100
整数
只是为了将其转换回
双精度
。然而,这似乎是执行截断的唯一方法。有点离题:我想知道在例如
Double->Double
转换的情况下,是否会对其进行优化。我的意思是,将
1e100
转换为
整数
,只是为了协同转换似乎很愚蠢将其重新输入到
双精度
。但是,这似乎是执行截断的唯一方法。