错误"无法推断(a~b)"是什么意思?

asd*_*234 2 haskell types

我正在修改以下代码作为任务的一部分:

rand :: Random a => State StdGen a
rand = do
    gen <- get
    let (x, gen') = random gen
    put gen'
    return x
Run Code Online (Sandbox Code Playgroud)

我被要求编写一个函数randR来完成与函数相同的任务,rand但允许指定范围.所需的类型是Random a => (a, a) -> State StdGen a.我写了以下代码:

randR :: Random a => (a, a) -> State StdGen b
randR (lo, hi) = do
    gen <- get
    let (x, gen') = randomR (lo, hi) gen
    put gen'
    return x
Run Code Online (Sandbox Code Playgroud)

这看起来正确; 它几乎就像模型一样.但是我收到以下错误:

Could not deduce (a ~ b)
from the context (Random a)
  bound by the type signature for 
             randR :: Random a => (a, a) -> State StdGen b
Run Code Online (Sandbox Code Playgroud)

什么(a ~ b)意思,为什么编译器不能从"上下文"中"推断"它?

Chr*_*kle 7

错误消息表明签名中存在拼写错误randR:randR :: Random a => (a, a) -> State StdGen b.它应该是... -> RandState a.

该消息粗略地表明编译器知道a并且b需要是相同的类型,但它不能证明是这种情况.a ~ b是一种"平等约束" ; 读~作粗略的含义=.

有关上下文的部分只是告诉你它的编译器的方式知道类型的限制.在这种情况下,它几乎完全没有用,但经常你会看到类似的东西,Could not deduce (Floating a) from the context (Num a)或者其他一些简单的指示,即函数需要一个额外的约束.

顺便说一句,有了一些扩展,你可以通过添加GHC要求的约束解决这个问题:randR :: (Random a, a ~ b) => (a, a) -> State StdGen b应该正常工作.(我想.)为了你的目的,不要担心这个......