2017-03-05 142 views
3

我的功能不起作用。我尝试了许多不同的类型签名。如果我删除了类型签名,它不能用点号作为“p”。Haskell类型签名错误

fak :: (Num a, Ord a) => a->a 
fak x 
    | x <= 1 = 1 
    | otherwise = x*fak (x-1) 

ncr :: Integral a => a -> a -> a 
ncr n k = (fak n) `div` (fak(n-k) * fak k) 

bTable :: (Integral a, Num b) => a->b->a->a 
bTable n p k = (ncr n k) * p^k * (1-p)^(n-k) 

推断类型不是一般的足够

*** Expression : bTable 
*** Expected type : (Integral a, Num b) => a -> b -> a -> a 
*** Inferred type : (Integral a, Num a) => a -> a -> a -> a 

如果我删除类型签名,我得到:

:t bTable 
bTable :: Integral a => a -> a -> a -> a 

但是如果我输入:

bTable 50 0.8 10 

我得到

Unresolved overloading 
*** Type  : (Fractional a, Integral a) => a 
*** Expression : bTable 50 0.8 10 
+3

有在Haskell中没有自动类型转换。如果你有'a * b','a'和'b'必须是相同的类型。你如何期望在某些功能乘以别的东西后得到'0.8'中的'Integral'类型? –

回答

4

使用fromIntegralncr返回值转换的东西,你可以用Num a => a值乘。

bTable n p k = fromIntegral (ncr n k) * p^k * (1-p)^(n-k) 

注推断出的类型此功能是那么

bTable :: (Num a, Integral b) => b -> a -> b -> a 

,则略有不同,你尝试声明的类型(有改名比较上述类型约束)

bTable :: (Num a, Integral b) => b -> a -> b -> b