这个问题是在阅读有关应用函子的优秀《Learn You a Haskell》的新章节时出现的。

作为 Maybe 实例定义的一部分,Applicative 类型类具有:

pure = Just

如果我只是转到 GHCi 并导入 Control.Applicative,然后执行以下操作:

pure (3+)

我什么也没得到(有道理)。但如果我在表达式的一部分中使用它:

pure (3+) <*> Just 4

我只得到7。我想这也不足为奇,但我认为,我缺少关于类型类如何工作的一些完整内容,即调用没有歧义 pure 这里。

如果我的困惑有道理,谁能详细解释一下发生了什么?

有帮助吗?

解决方案

这只是类型推断。 (<*>)运算符需要两个参数才能使用相同的Applicative实例。右侧是Maybe,所以左侧也必须是:t expression。这就是它如何确定这里使用的实例。您可以通过键入<=>来查看解释器中任何表达式的类型,也许如果您只是浏览每个子表达式并查看推断的类型,您将更好地了解正在发生的情况。

其他提示

值得查看编译器推断的类型pure (3+)

Prelude Control.Applicative> :t pure (3+)
pure (3+) :: (Num a, Applicative f) => f (a -> a)

此术语的类型已重载,关于数字类和应用类的决定会延迟到稍后。但您可以使用注释强制特定类型,例如:

*Showfun Control.Applicative> pure (3+) :: Maybe (Double -> Double)
Just <function>

(这是因为Showfun有一个实例声明,它将函数值打印为<function>。)

这只是编译器何时积累了足够的信息才能做出决定的问题。

要扩展newacct的答案,如果没有足够的信息来推断实际类型,编译器可能(在某些情况下)尝试选择默认类型,仅限于满足相关类型约束的类型。在这种情况下,对于某些难以确定的Num = <!> gt的实例,推断的类型是IO(n - <!>>; n); ñ。然后GHCi对其进行评估并抛弃返回值,但没有明显效果。

这是一个有趣的 SO 线程类型推断. 。不是 Haskell 特有的,但是有很多关于函数式语言中类型推断的好链接和内容可供阅读。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top