What does the 22 :: Int
mean here?
rotor3=("BDFHJLCPRTXVZNYEIWGAKMUSQO",22::Int)
CodePudding user response:
22 :: Int
expresses the same value as 22
by itself, but with additional information to the compiler to treat it specifically as type Int
.
Now you may wonder, doesn't 22
have type Int
anyway? It does in many other programming languages, but in Haskell it has out of the box a more general type Num a => a
, meaning it can have any numerical type, depending on what the context demands. This is necessary because Haskell doesn't have automatic conversion of types. For example, if you write sin 22
, the literal 22
will be treated as having the type Double
, in ['a'..'z']!!22
it'll be treated as having the type Int
, and in 22^9
it'll be treated as having the type Integer
.
ghci> sin 22
-8.851309290403876e-3
ghci> ['a'..'z']!!22
'w'
ghci> 22^100
174690015040882455988354400790170000897162886859579152352704471899874163427116241050767381769631464055938734482112142486751362076901376
Manually specifying the type to Int
, or some other concrete type, prevents this automatic type selection. In the above examples this would cause some problems:
ghci> ['a'..'z']!!(22::Float)
<interactive>:8:14: error:
• Couldn't match expected type ‘Int’ with actual type ‘Float’
• In the second argument of ‘(!!)’, namely ‘(22 :: Float)’
In the expression: ['a' .. 'z'] !! (22 :: Float)
In an equation for ‘it’: it = ['a' .. 'z'] !! (22 :: Float)
ghci> sin (22::Int)
<interactive>:5:1: error:
• No instance for (Floating Int) arising from a use of ‘sin’
• In the expression: sin (22 :: Int)
In an equation for ‘it’: it = sin (22 :: Int)
ghci> (22::Int)^100 -- overflow
0
But sometimes it is necessary to give the compiler some concrete information about what types you want, since it can otherwise be ambiguous. A typical example if when you read values from a string: the following doesn't work
ghci> read "22"
*** Exception: Prelude.read: no parse
What's happening here is that absent any info as which type you want to read the string, the compiler (which isn't aware that the string contains at runtime a number) picks the most simple type it could be, namely ()
. But there's only one value that parses for that type:
ghci> read "()"
()
To actually parse a number, you need to explicitly say its type:
Prelude> read "22" :: Int
22
Prelude> read "22" :: Double
22.0
Note that this is not necessary if the type can be inferred from the context:
ghci> ['a'..'z'] !! read "22"
'w'
(BTW using read
is widely considered a bad idea, because of the potential for runtime errors; better use readMaybe
.)
CodePudding user response:
22
is a constant that can be of any numeric type: Int,Integer,Float,Double,....
and many others.
By annotating it with a type as in 22::Int
, we require the second component of the pair rotor3
to have type Int
.
Another option (which I personally prefer) is to annotate rotor3
directly.
rotor3 :: (String, Int)
rotor3 = ("BDFHJLCPRTXVZNYEIWGAKMUSQO", 22)
In this case the 22
is automatically inferred to be an Int
constant.