Haskell 哈斯凯尔:没有任何实例出现
从Haskell开始,我经常遇到类型问题(以及GHC中不太有用的错误消息)。我定义了以下功能: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”而产生的
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
转换为整数
,只是为了协同转换似乎很愚蠢将其重新输入到双精度。但是,这似乎是执行截断的唯一方法。