实现Wiener';Haskell中的s算法-没有因使用'wiener';
我试图在Haskell中实现《密码学:理论与实践》第三版中的维纳算法。以下是我到目前为止所写的内容:实现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
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))