Home > Mobile >  What does the 22::Int mean here?
What does the 22::Int mean here?

Time:11-05

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.

  • Related