在ghci中调用来自泛型函数的结果的show

时间:2016-04-16 15:55:04

标签: haskell typeclass

当你使用特定类型类的函数时,我对GHCI中的这个东西感到有点困惑,但没有指定你想要的具体类型。请考虑以下代码:

pure (1+) <*> pure 1
> 2

我理解它的方式,当你在GHCI中键入内容时,它会评估表达式并在其上调用putStrLn . show。但是如何评估呢?为什么这2?我的意思是,它是有意义的,对于大多数应用实例来说它可能是2,但是没有办法确定,对吧?如果我们检查表达式的类型:

pure (1+) <*> pure 1 :: (Num b, Applicative f) => f b

好吧,公平地说,类型看起来合理,但是从来没有指定任何类型类实例,那么GHCI / Haskell如何知道在我写pure / <*>时要调用哪个函数?< / p>

来自其他语言的直觉告诉我这应该是一个错误。有点像试图用OOP语言静态调用实例方法(显然不一样,但这就是我得到的那种感觉)。

这里发生了什么?

1 个答案:

答案 0 :(得分:5)

由于ghci的两个特点:

  1. type defaulting,将Num b => b解析为Integer(注意1实际上是fromInteger 1,您可以定义 - 但不推荐 - 一些数字fromInteger 1 + fromInteger 1 == kshow k == "3"的数据类型,这一点很重要):
  2. 整个ghci在IO monad和if an expression can be instantiated to an IO action, then it will be中运行,因此Applicative f => f已解析为IO。如果表达式的类型为C1 f => f a,并且IO不是该类型类C1的实例,则ghci将引发歧义错误。