多数逻辑解码Haskell

时间:2014-09-25 14:21:08

标签: haskell logic decoding

我必须计算正确解码复制n次的位的概率。 以下公式应该是答案:

the formula

在Haskell中,我将其编码如下:

fac 1 = 1
fac n = fac (n-1) * n
--prob :: (Integral b, Fractional b) => (b, b) -> b
--prob :: (Int,Int) -> Double
prob (n, k)
    | n==k = (0.01**k)
    | otherwise = factor (n, k) * (0.01 ** k) * (0.99**(n-k)) + prob (n, (k+1)) 
    where
        factor (n, k) = (fac n / ((fac k)* (fac n-k)))

1 - prob (3,2)会提供结果0.99992575,这是不正确的,因为它应该是0.99970。有谁知道我哪里出错了?

2 个答案:

答案 0 :(得分:6)

原因是功能优先。 如果你看一下prob的定义,你会看到:

(fac n-k)

因为函数应用程序具有最优先级,因此将其解析为

((fac n) - k)

所以你的代码应该是

(fac (n-k))

在我的电脑上得到0.999702的结果。

答案 1 :(得分:0)

这些是代码缺乏的几个最佳实践。我事实上已经回答了这个问题。

1-不要使用元组作为输入。在Haskell中,函数可以有多个参数。语法为f x y,用于在fx上调用y。类型也有类似的语法。这会将您的代码转换为:

fac 1 = 1
fac n = fac (n-1) * n
--prob :: (Integral b, Fractional b) => b -> b -> b (two parameters of type b and output of type b)
--prob :: Int -> Int -> Double
prob n k
    | n==k = (0.01**k)
    | otherwise = factor n k * (0.01 ** k) * (0.99**(n-k)) + prob n (k+1) 
    where
        factor n k = (fac n / ((fac k)* (fac (n-k))))

2-如果您注意到,fac仅适用于整数,factor同样适用。因此,prob infact的类型为(Fractional a, Integral b) -> b -> b -> aInteger -> Integer -> Float。为什么不给他们真正的类型?

此转换需要将**(获取两个浮点数)更改为^(获取整数作为其第二个参数)并使用函数fromIntegral将整数转换为任意数字的数据。

fac :: Integral a => a -> a -- or alternatively Integer -> Integer
fac 1 = 1
fac n = fac (n-1) * n
prob n k
    | n==k = (0.01 ^^ k)
    | otherwise = fromIntegral (factor n k) * (0.01 ^^ k) * (0.99 ^^ (n-k) + prob n (k+1) 
    where
        factor n k = div (fac n) (fac k * fac (n-k)) -- div is Integer division operator.

现在prob的类型为(Integral a, Floating b) => a -> a -> b,这意味着它会获得两个类型a的参数(这是一个Integral实例),并返回类型为b的值。< / p>