【问题标题】:How does Haskell know which typeclass instance you mean?Haskell 如何知道您指的是哪个类型类实例?
【发布时间】:2009-05-03 16:47:15
【问题描述】:

在阅读优秀的 Learn You a Haskell 中关于应用函子的新章节时出现了这个问题。

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

pure = Just

如果我只是去 GHCi 并导入 Control.Applicative,然后这样做:

pure (3+)

我什么都不懂(有道理)。但是如果我在表达式的一部分中使用它:

pure (3+) <*> Just 4

我只有 7 个。我想这也不足为奇,但我认为关于类型类如何工作的一些不可或缺的东西,我认为这里对 pure 的调用没有歧义。

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

【问题讨论】:

    标签: haskell type-inference typeclass


    【解决方案1】:

    这只是类型推断。 (&lt;*&gt;) 运算符要求两个参数使用相同的 Applicative 实例。右侧是Maybe,所以左侧也必须是Maybe。这就是它如何确定此处使用的实例。您可以通过键入:t expression 来查看解释器中任何表达式的类型,也许如果您只是查看每个子表达式并查看推断的类型,您会更好地了解正在发生的事情。

    【讨论】:

    • 啊,编译器是不是做了类似“嗯,这个参数的类型不明确,所以让我检查下一个参数的类型然后再回来”之类的事情吗?
    • 类型推断非常复杂,但值得知道它不是一步完成的。类型推断器通常在一个步骤中收集一些信息,然后在稍后阶段收集更多信息。因此,它不仅仅是从左到右一次性推断出所有内容的正确类型。在这种情况下,它将推断pure(Applicative a1) =&gt; a1 (Int -&gt; Int) 类型,其中a1 只是一个组成的类型变量,在类型推断的后期阶段,它将得出结论a1 必须是Maybe,然后它将在任何地方用Maybe 替换a1
    • 谢谢——这很有帮助!
    【解决方案2】:

    值得看看编译器为 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 有一个将函数值打印为&lt;function&gt; 的实例声明。)

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

    【讨论】:

    • 出于好奇,Showfun 模块是在某个现有包中,还是只是您自己编写的?实现很简单:instance Show (a -&gt; b) where; show _ = "&lt;function&gt;"
    • 我自己写了 Showfun,所以我可以使用 Just 打印示例 pure (3+)
    • ShowFunctions 现在在 QuickCheck 中,我相信。
    【解决方案3】:

    为了扩展 newacct 的答案,如果没有足够的信息来推断实际类型,编译器可能(在某些情况下)尝试选择默认类型,仅限于那些满足相关类型约束的类型.在这种情况下,对于一些难以确定的 Num => n 实例,推断的类型是 IO (n -> n)。 GHCi 然后评估它并丢弃返回值,没有可见的效果。

    【讨论】:

      【解决方案4】:

      这是一个有趣的SO thread on type inference。不是 Haskell 特有的,但有很多关于函数式语言类型推断的好链接和资料可供阅读。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-28
        • 1970-01-01
        • 1970-01-01
        • 2015-09-07
        • 2016-08-12
        • 1970-01-01
        • 2013-08-17
        • 1970-01-01
        相关资源
        最近更新 更多