当你使用特定类型类的函数时,我对GHCI中的这个东西感到有点困惑,但没有指定你想要的具体类型.请考虑以下代码:
pure (1+) <*> pure 1
> 2
Run Code Online (Sandbox Code Playgroud)
我理解它的方式,当你在GHCI中键入内容时,它会评估表达式并调用putStrLn . show
它.但是如何评估呢?为什么这2?我的意思是,它是有意义的,对于大多数应用实例来说它可能是2,但是没有办法确定,对吧?如果我们检查表达式的类型,我们得到:
pure (1+) <*> pure 1 :: (Num b, Applicative f) => f b
Run Code Online (Sandbox Code Playgroud)
好吧,公平,类型看起来合理,但是从来没有指定任何类型类实例,所以GHCI/Haskell如何知道在写pure
/ 时要调用什么函数<*>
?
来自其他语言的直觉告诉我这应该是一个错误.有点像试图用OOP语言静态调用实例方法(显然不一样,但这是我得到的那种感觉).
这里发生了什么?
这是由于ghci的两个特点:
Num b => b
对Integer
(请注意,1
实际上是fromInteger 1
你可以定义-但不建议报告-某些数字数据类型,其中fromInteger 1 + fromInteger 1 == k
和show k == "3"
,所以这个问题):Applicative f => f
被解析为IO
.如果表达式是类型C1 f => f a
,并且IO
不是该类型类的实例C1
,则ghci将引发歧义错误.