在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’
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
有什么问题?
答案 0 :(得分:3)
由于read
是一个多态函数,read "3" + 4
有效,因为编译器知道您需要Num
,因为您已将+
应用于read "3"
,如果编译器无法弄清楚你想要什么,你必须指定read
的类型,如下所示:
Prelude> let rd = read :: String->(Int,Int)
Prelude> rd "(1,2)"
答案 1 :(得分:1)
首先,让我们看一下read
的类型签名:
Prelude> :t read
read :: Read a => String -> a
如您所见,其返回值必须具有Read
类型类的类型。但是,如果我们不使用该值,编译器就不会知道它是什么类型。
在这种情况下,我们可以添加::
来指定其类型。
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有静态类型,所以在编译之前必须知道所有类型。