Haskell类型签名错误

3

我的函数不起作用。我尝试了许多不同的类型签名。如果我删除类型签名,它不能使用点数作为“p”。

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,则ab必须是相同的类型。如果要将0.8的某个幂乘以其他内容并得到一个Integral类型,这是不可能的。 - n. m.
1个回答

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 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接