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
2条答案
按热度按时间chhkpiq41#
22 :: Int
本身表示与22
相同的值,但向编译器提供了附加信息,以便将其特别视为Int
类型。现在你可能想知道,
22
不是有Int
* 类型吗?在许多其他编程语言中都有,但在Haskell中它有一个更通用的Num a => a
类型,这意味着它可以有任何数字类型,这取决于上下文的要求。这是必要的,因为Haskell没有类型的自动 * 转换 *。例如,如果你写sin 22
,字面量22
将被视为具有Double
类型,在['a'..'z']!!22
中,它将被视为具有Int
类型,在22^9
中,它将被视为具有Integer
类型。手动将类型指定为
Int
或其他具体类型,会阻止自动选择类型。在上面的示例中,这会导致一些问题:但是有时候需要给予编译器一些具体的信息,告诉你想要什么类型,因为它可能是不明确的。一个典型的例子是当你从一个字符串中读取值时:以下内容不起作用
这里发生的事情是,如果没有任何信息 * 作为你想要读取的字符串的类型 *,编译器(它不知道字符串在运行时包含一个数字)会选择最简单的类型,即
()
。但只有一个值可以解析该类型:要真正解析一个数字,你需要明确地说出它的类型:
请注意,如果可以从上下文推断类型,则 * 不 * 需要这样做:
(BTW使用
read
被广泛认为是一个坏主意,因为可能会出现运行时错误;最好使用readMaybe
。)9udxz4iz2#
22
是一个常数,可以是 * 任何 * 数值类型:Int,Integer,Float,Double,....
和许多其它的。通过使用
22::Int
中的类型对其进行注解,我们要求rotor3
对中的第二个组件具有Int
类型。另一种选择(我个人更喜欢)是直接注解
rotor3
。在这种情况下,
22
被自动推断为Int
常量。