混淆ghci中的类型

时间:2015-10-10 13:07:45

标签: haskell functional-programming monomorphism-restriction

这是我的代码:

n = [(a,b) | a <- [1..5],b <- [1..5]]
calcBmis xs = [bmi | (w, h) <- xs,let bmi = w / h ^ 2]  

尝试将calcBmis应用于n时,出现以下错误:

*Charana> calcBmis n

<interactive>:220:1:
    No instance for (Fractional Integer)
    arising from a use of ‘calcBmis’
    In the expression: calcBmis n
    In an equation for ‘it’: it = calcBmis n

进一步调查ghci:

*Charana> :t calcBmis
calcBmis :: Fractional t => [(t, t)] -> [t]
*Charana> :t n
n :: [(Integer, Integer)]

我所假设的是我生成的列表属于(Integer,Integer)类型,但无法在calcBmis中处理,只需Fractional。知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

您可以使用111111111111代替div

(/)

正如您所看到的,此版本可以处理所有calcBmis xs = [ bmi | (w,h) <- xs, let bmi = (w `div` h)^2 ] Prelude> :t calcBmis calcBmis :: Integral t => [(t, t)] -> [t] Prelude> calcBmis n [1,0,0,0,0,4,1,0,0,0,9,1,1,0,0,16,4,1,1,0,25,4,1,1,1] 值 - 但当然会截断(因为Integral)。

或者您可以使用div

映射所有内容
fromIntegral

然后将产生小数值:

calcBmis xs = [ bmi | (w,h) <- xs, let bmi = (fromIntegral w / fromIntegral h)^2 ]

Prelude> :t calcBmis
calcBmis:: (Fractional t, Integral t1, Integral t2) => [(t1, t2)] -> [t]

在任何一种情况下,只要它们是Prelude> calcBmis n [1.0,0.25,0.1111111111111111 ,6.25e-2 ,4.000000000000001e-2 ,4.0 ,1.0 ,0.4444444444444444 , ... ] 的实例,它就可以用于所有输入 - 第二个版本甚至可以接受不同积分的对;)