haskell 这里的22::Int是什么意思?

wko9yo5t  于 2022-11-14  发布在  其他
关注(0)|答案(2)|浏览(167)

这里的22 :: Int是什么意思?

rotor3=("BDFHJLCPRTXVZNYEIWGAKMUSQO",22::Int)
chhkpiq4

chhkpiq41#

22 :: Int本身表示与22相同的值,但向编译器提供了附加信息,以便将其特别视为Int类型。
现在你可能想知道,22不是有Int * 类型吗?在许多其他编程语言中都有,但在Haskell中它有一个更通用的Num a => a类型,这意味着它可以有任何数字类型,这取决于上下文的要求。这是必要的,因为Haskell没有类型的自动 * 转换 *。例如,如果你写sin 22,字面量22将被视为具有Double类型,在['a'..'z']!!22中,它将被视为具有Int类型,在22^9中,它将被视为具有Integer类型。

ghci> sin 22
-8.851309290403876e-3
ghci> ['a'..'z']!!22
'w'
ghci> 22^100
174690015040882455988354400790170000897162886859579152352704471899874163427116241050767381769631464055938734482112142486751362076901376

手动将类型指定为Int或其他具体类型,会阻止自动选择类型。在上面的示例中,这会导致一些问题:

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

但是有时候需要给予编译器一些具体的信息,告诉你想要什么类型,因为它可能是不明确的。一个典型的例子是当你从一个字符串中读取值时:以下内容不起作用

ghci> read "22"
*** Exception: Prelude.read: no parse

这里发生的事情是,如果没有任何信息 * 作为你想要读取的字符串的类型 *,编译器(它不知道字符串在运行时包含一个数字)会选择最简单的类型,即()。但只有一个值可以解析该类型:

ghci> read "()"
()

要真正解析一个数字,你需要明确地说出它的类型:

Prelude> read "22" :: Int
22
Prelude> read "22" :: Double
22.0

请注意,如果可以从上下文推断类型,则 * 不 * 需要这样做:

ghci> ['a'..'z'] !! read "22"
'w'

(BTW使用read被广泛认为是一个坏主意,因为可能会出现运行时错误;最好使用readMaybe。)

9udxz4iz

9udxz4iz2#

22是一个常数,可以是 * 任何 * 数值类型:Int,Integer,Float,Double,....和许多其它的。
通过使用22::Int中的类型对其进行注解,我们要求rotor3对中的第二个组件具有Int类型。
另一种选择(我个人更喜欢)是直接注解rotor3

rotor3 :: (String, Int)
rotor3 = ("BDFHJLCPRTXVZNYEIWGAKMUSQO", 22)

在这种情况下,22被自动推断为Int常量。

相关问题