Haskell 为什么可以';你能猜出正确的类型吗?
在Haskell中,我可以使用Haskell 为什么可以';你能猜出正确的类型吗?,haskell,type-inference,typeclass,Haskell,Type Inference,Typeclass,在Haskell中,我可以使用read从字符串生成Haskell值 Prelude> read "1" + 3 4 我可以使用fst获取第一个元素 Prelude> fst (1,2) 1 但是,当我将read和fst组合以获取第一个元素时,会出现一个错误: Prelude> fst (read "(1,2)") <interactive>:20:6: Could not deduce (Read b0) arising from a use of ‘
read
从字符串生成Haskell值
Prelude> read "1" + 3
4
我可以使用fst
获取第一个元素
Prelude> fst (1,2)
1
但是,当我将read
和fst
组合以获取第一个元素时,会出现一个错误:
Prelude> fst (read "(1,2)")
<interactive>:20:6:
Could not deduce (Read b0) arising from a use of ‘read’
from the context (Read a)
bound by the inferred type of it :: Read a => a
at <interactive>:20:1-18
The type variable ‘b0’ is ambiguous
Prelude>fst(读“(1,2)”)
:20:6:
无法推断(读取b0)因使用“读取”而产生
从上下文(读a)
由它的推断类型绑定::Read a=>a
时间:20:1-18
类型变量“b0”不明确
问题是什么?由于
读取
是一个多态函数,因此读取“3”+4
可以工作,因为编译器知道您需要一个Num
,因为您将+
应用于读取“3”
,如果编译器无法理解您需要的内容,则必须指定读取的类型,如下所示:
Prelude> let rd = read :: String->(Int,Int)
Prelude> rd "(1,2)"
首先,让我们看看read
的类型签名:
Prelude> :t read
read :: Read a => String -> a
正如您所看到的,它的返回值的类型必须是Read
typeclass。但是,如果我们不使用该值,编译器将不知道它是什么类型
在这种情况下,我们可以添加:
来指定其类型
Prelude> read "5"
*** Exception: Prelude.read: no parse
Prelude> read "5" :: Int
5
同样地
Prelude> read "(1, 2)"
*** Exception: Prelude.read: no parse
Prelude> read "(1, 2)" :: (Int, Int)
(1,2)
Prelude> fst (read "(1,2)" :: (Int, Int))
1
编译器在大多数情况下都可以推断出类型,但是当它遇到read“5”
时,它可能会对类型应该是Int
还是Float
或其他任何内容感到困惑。只有经过计算,Haskell才能知道它的类型。另一方面,Haskell有静态类型,因此它必须在编译前知道所有类型的详细信息:你必须指定类型,只要没有其他东西可以为你做(参见问题中的第一个示例,它工作得很好)。第一个示例只适用于数字默认值“只有在计算之后,Haskell才能知道它的类型”,你的意思是你需要使用这个值,这样编译器才能知道它的类型吗?