Joh*_*ler 0 haskell tuples equality
我只是挖掘了一下Haskell,我开始尝试计算文本中两个单词的Phi-Coefficient.但是,我遇到了一些我无法解释的非常奇怪的行为.
在删除所有内容后,我最终使用此代码重现问题:
let sumTup = (sumTuples?concat) frequencyLists
let sumFixTup = (138, 136, 17, 204)
putStrLn (show ((138, 136, 17, 204) == sumTup))
putStrLn (show (phi sumTup))
putStrLn (show (phi sumFixTup))
Run Code Online (Sandbox Code Playgroud)
这输出:
True
NaN
0.4574206676616167
Run Code Online (Sandbox Code Playgroud)
因此虽然sumTup和sumFixTup显示相同,但它们在传递时表现不同phi.
定义phi是:
phi (a, b, c, d) =
let dividend = fromIntegral(a * d - b * c)
divisor = sqrt(fromIntegral((a + b) * (c + d) * (a + c) * (b + d)))
in dividend / divisor
Run Code Online (Sandbox Code Playgroud)
这可能是整数溢出的情况.fromIntegral在你的除数中传入的值是3191195800,它大于32位有符号Int可以容纳的值.
在ghci(或任何你正在使用的)中,使用
:t sumTup
:t sumFixTup
Run Code Online (Sandbox Code Playgroud)
看看那些变量的类型.我猜你会发现,sumTup是(Int, Int, Int, Int)(溢)和sumFixTup是(Integer, Integer, Integer, Integer)(不溢出).
编辑:第二个想法,Ints的元组不能等于整数元组.即便如此,我认为ghci会将类型固定sumFixTup为整数元组,而sumTup可能有一种形式(Num a) => (a, a, a, a)或者(Integral a) => (a, a, a, a),这取决于定义它的函数.
然后将GHCI它们转换为整数与之比较sumFixTup,但可以将它们计算除数时转换为整数的phi,造成溢出.
另一个编辑:KennyTM,你是对的一半:
Prelude> :t (1,2,3,4)
(1,2,3,4) :: (Num t, Num t1, Num t2, Num t3) => (t, t1, t2, t3)
Prelude> let tup = (1,2,3,4)
Prelude> :t tup
tup :: (Integer, Integer, Integer, Integer)
Run Code Online (Sandbox Code Playgroud)
所以对于问题中给出的例子:
putStrLn (show ((138, 136, 17, 204) == sumTup))
Run Code Online (Sandbox Code Playgroud)
文字(138, 136, 17, 204)被推断为Int匹配的元组sumTup,并且它们相等.
putStrLn (show (phi sumTup))
Run Code Online (Sandbox Code Playgroud)
sumTup由Ints 组成,如上所述导致溢出.
putStrLn (show (phi sumFixTup))
Run Code Online (Sandbox Code Playgroud)
sumFixTup由Integers 组成,给出正确的结果.请注意,sumTup并且sumFixTup从未直接进行比较,因此我之前的编辑基于误读.