[英]Haskell Integer and Int types; conversion not working
I'm trying to solve Project Euler problem 59, where I have to xor-decrypt a message that has a three-character key (all lowercase). 我正在尝试解决Project Euler问题59,我必须对具有三个字符键(全部小写)的消息进行xor解密。 In ASCII this would mean the set of all keys is
在ASCII中,这意味着所有键的集合是
let keys = [[a, b, c] | a <- [97..122], b <- [97..122], c <- [97..122]]
and the following functions would together heuristically decrypt it: 并且以下函数将一起启发式地解密它:
decrypt :: [Int] -> [Int] -> [Char]
decrypt msg xs = map chr $ zipWith xor msg $ (concat . repeat) xs
try :: [[Int]] -> [Int] -> [Char]
try kys msg = head $ filter (isInfixOf "the") $ map (decrypt msg) kys
where basically I keep on trying keys until one of them decrypts the message to have a "the" in it (I know the message has common English words). 基本上我继续尝试按键,直到其中一个人解密消息,其中有一个“the”(我知道该消息有常见的英文单词)。 But when I bind
keys
and message
and run try keys message
I get 但是当我绑定
keys
和message
并运行try keys message
我得到了
Couldn't match expected type `Int' with actual type `Integer'
Expected type: [[Int]]
Actual type: [[Integer]]
In the first argument of `try', namely `keys'
In the expression: try keys message
Now, even when I say let keys = [map fromIntegral [a, b, c] | a <- [97..122], b <- 97..122],, c <- [97..122]]
现在,即使我说
let keys = [map fromIntegral [a, b, c] | a <- [97..122], b <- 97..122],, c <- [97..122]]
let keys = [map fromIntegral [a, b, c] | a <- [97..122], b <- 97..122],, c <- [97..122]]
it still says it has type Integer
and not Int
and also when I try let keys = map (map fromIntegral) keys
, and also when I use fromInteger
. let keys = [map fromIntegral [a, b, c] | a <- [97..122], b <- 97..122],, c <- [97..122]]
它仍然说它有类型Integer
而不是Int
,当我尝试let keys = map (map fromIntegral) keys
,以及当我使用fromInteger
。 What's going on? 这是怎么回事?
The problem is that the type of keys
defaults to [[Integer]]
. 问题是
keys
的类型默认为[[Integer]]
。 Override this by adding a type annotation when defining keys
: 通过在定义
keys
时添加类型注释来覆盖它:
let keys = ... :: [[Int]]
This is because the type of numeric literals (and the return type of fromIntegral
) is polymorphic, so when you write let keys = ...
the monomorphism restriction kicks in and defaults the numeric types to Integer
unless they're constrained in some other way. 这是因为数字文字的类型(以及
fromIntegral
的返回类型)是多态的,所以当你写let keys = ...
, 单态限制会启动并将数值类型默认为Integer
除非它们以某种其他方式受到约束。
> let x = 42
> :t x
x :: Integer
> let y = 42 :: Int
> :t y
y :: Int
Another solution is to disable the monomorphism restriction. 另一种解决方案是禁用单态限制。 Then
keys
will be a polymorphic value which will be specialized to [[Int]]
when you try to use it. 然后
keys
将是一个多态值,当您尝试使用它时,它将专门用于[[Int]]
。
> :set -XNoMonomorphismRestriction
> let x = 42
> :t x
x :: Num b => b
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.