实现Wiener';Haskell中的s算法-没有因使用'wiener';

实现Wiener';Haskell中的s算法-没有因使用'wiener';,haskell,cryptography,Haskell,Cryptography,我试图在Haskell中实现《密码学:理论与实践》第三版中的维纳算法。以下是我到目前为止所写的内容: import Data.List wiener e n = factors where euclid = euclidean e n cs = 1 : head euclid : rest cs euclid ds = 0 : 1 : rest ds euclid ns = filter isInt $ drop 2 $ zi

我试图在Haskell中实现《密码学:理论与实践》第三版中的维纳算法。以下是我到目前为止所写的内容:

import Data.List

wiener e n = factors
    where euclid = euclidean e n
          cs = 1 : head euclid : rest cs euclid
          ds = 0 : 1 : rest ds euclid
          ns = filter isInt $ drop 2 $ zipWith (\x y -> (x * e - 1) / y) ds cs
          qs = map (\x -> quad 1 (x - n - 1) n) ns
          factors = find (\(p, q) -> isInt p && 0 < p && p < n 
                                  && isInt q && 0 < q && q < n) qs
          rest xs ys = zipWith (+) xs (zipWith (*) (tail ys) (tail xs))

euclidean _ 0 = []
euclidean a b = a `div` b : euclidean b (a `mod` b)

quad a b c
    | d > 0     = ((-b + sqrt d) / (2 * a), (-b - sqrt d) / (2 * a))   
    | otherwise = (0.0, 0.0) 
    where d = b * b - 4 * a * c

isInt x = x == fromInteger (round x)

我应该如何进行?是否有任何通用的数字类型可以在任何地方使用?

我找到了错误。
euclidean
的返回类型是
Integral a=>[a]
,而
quad
返回
RealFrac
的实例。由于使用值
n
e
作为两个函数的参数,
n
e
必须是这两个类型类的实例

wiener :: (Floating b, Integral a, RealFrac b) => a -> a -> Maybe (b,b)
wiener e' n' = factors
    where euclid = map fromIntegral $ euclidean e' n'  -- convert result from `Integral` to `Num`
          e = fromIntegral e'                          -- convert Integral to Num
          n = fromIntegral n'
          cs = 1 : head euclid : rest cs euclid
          ds = 0 : 1 : rest ds euclid
          ns = filter isInt $ drop 2 $ zipWith (\x y -> (x * e - 1) / y) ds cs
          qs = map (\x -> quad 1 (x - n - 1) n) ns
          factors = find (\(p, q) -> isInt p && 0 < p && p < n 
                                  && isInt q && 0 < q && q < n) qs
          rest xs ys = zipWith (+) xs (zipWith (*) (tail ys) (tail xs))
wiener::(浮动b,积分a,realfracb)=>a->a->Maybe(b,b)
维纳e'n'=因子
其中,欧几里德=映射自整数$euclidean e'n'--将结果从'Integral'转换为'Num'`
e=从整数e'--将整数转换为数值
n=从积分n'
cs=1:头部欧几里德:其余cs欧几里德
ds=0:1:rest ds欧几里得
ns=过滤器isInt$drop 2$zipWith(\x y->(x*e-1)/y)ds cs
qs=map(\x->quad1(x-n-1)n)ns
因子=发现(\(p,q)->存在p&0
It typechecks对我来说很好。GHCi给了我这些类型:
wiener::(浮点a,积分a,realfraca)=>a->a->Maybe(a,a)
euclidean::Integral a=>a->a->a->[a]
quad:(浮点t,Ord t)=>t->t->t->t->(t,t)
isInt::RealFrac a=>a->Bool
。这也为我进行了类型检查。。是的,它进行了类型检查。我的错。但是,尝试使用
wiener 238123333 293719721
会给我:
没有因使用“wiener”而产生的实例(RealFrac a0)
,也没有因文字“238123333”而产生的实例(Num a0)
(238123333::Int)
或任何您想要的具体类型。问题是,GHCi无法猜出您想要使用哪种具体类型。啊哈,它没有进行类型检查!这通常是件好事。如果没有签名,GHC可能会为一个函数推断出一些完全荒谬的类型,这会在其他地方导致更加模糊的问题。如果由于给定的签名不起作用而导致编译错误,那么通常很容易找到错误(尽管不可否认,这需要一些练习,因为GHC的许多错误消息都具有误导性)。太棒了!谢谢:-)
wiener :: (Floating b, Integral a, RealFrac b) => a -> a -> Maybe (b,b)
wiener e' n' = factors
    where euclid = map fromIntegral $ euclidean e' n'  -- convert result from `Integral` to `Num`
          e = fromIntegral e'                          -- convert Integral to Num
          n = fromIntegral n'
          cs = 1 : head euclid : rest cs euclid
          ds = 0 : 1 : rest ds euclid
          ns = filter isInt $ drop 2 $ zipWith (\x y -> (x * e - 1) / y) ds cs
          qs = map (\x -> quad 1 (x - n - 1) n) ns
          factors = find (\(p, q) -> isInt p && 0 < p && p < n 
                                  && isInt q && 0 < q && q < n) qs
          rest xs ys = zipWith (+) xs (zipWith (*) (tail ys) (tail xs))