为什么不能 read 推断出正确的类型?

Why can't read deduce the correct type?

在 Haskell 中,我可以使用 read.

从字符串中生成 Haskell 值
Prelude> read "1" + 3
4

我可以用fst得到第一个元素

Prelude> fst (1,2)
1

但是,当我组合 readfst 来获取第一个元素时出现错误:

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

有什么问题?

因为 read 是一个多态函数,所以 read "3" + 4 可以工作,因为编译器知道你想要 Num 因为你将 + 应用到 read "3",如果编译器不能弄清楚你想要什么,你必须指定类型 read,像这样:

Prelude> let rd = read :: String->(Int,Int)
Prelude> rd "(1,2)"

首先,让我们看一下read的类型签名:

Prelude> :t read
read :: Read a => String -> a

如您所见,它的 return 值必须具有 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有静态类型,所以它必须在编译前知道所有类型