为什么编译器不解析函数内的隐式约束类型变量?

Fix*_*int 1 haskell

这是代码:

class Problem p where
    readProblem :: String -> p
    solveProblem :: p -> String

readAndSolve = solveProblem . readProblem
Run Code Online (Sandbox Code Playgroud)

这是GHC产生的错误信息:

Ambiguous type variable `b0' in the constraint:
  (Problem b0) arising from a use of `readProblem'
Probable fix: add a type signature that fixes these type variable(s)
In the second argument of `(.)', namely `readProblem'
In the expression: solveProblem . readProblem
In an equation for `readAndSolve':
    readAndSolve = solveProblem . readProblem
Run Code Online (Sandbox Code Playgroud)

据我所知,我必须以某种方式告诉编译器使用的Problem实例solveProblemreadProblem类型相同,但我认为没有办法声明它.为什么不能自己解决这个问题呢?

Dan*_*her 8

您无需告诉编译器它必须是相同的类型,编译器会自行解决.但是,它无法确定使用哪种类型.这个问题的典型着名例子是

foo = show . read
Run Code Online (Sandbox Code Playgroud)

如果foo有合法类型,那就是

foo :: (Read a, Show a) => String -> String
Run Code Online (Sandbox Code Playgroud)

现在,编译器如何确定?

readAndSolve会有类型的

readAndSolve :: Problem p => String -> String
Run Code Online (Sandbox Code Playgroud)

  • 不,这是不可能的,编译器在开放世界假设下运行,就编译器所知,可以在其他地方定义更多实例.所以它永远不会在范围内选择唯一的实例. (4认同)
  • 如果只有一个实例,为什么要创建一个类型? (4认同)