【问题标题】:Explanation of partial application - join部分应用说明-join
【发布时间】:2012-08-13 16:24:18
【问题描述】:

为什么不同签名的函数的部分应用有效?

Control.Monad.join为例:

GHCi> :t (=<<)
(=<<) :: Monad m => (a -> m b) -> m a -> m b
GHCi> :t id
id :: a -> a
GHCi> :t (=<<) id
(=<<) id :: Monad m => m (m b) -> m b

为什么它接受id :: a -&gt; a 代替(a -&gt; m b) 参数,因为它们明显不同?

【问题讨论】:

    标签: haskell types partial-application


    【解决方案1】:

    =&lt;&lt; 的类型签名表明第一个参数是从 a(任何东西)到 b 的单子的函数。

    嗯,m b 算什么,对吧?所以我们可以用m b 替换每个a

    (=<<) :: Monad m => (m b -> m b) -> m (m b) -> m b
    

    ids 类型表示它是从任何事物到相同事物的函数。因此,如果我们加入 m b(不要忘记 monad 约束),我们会得到:

    id :: Monad m => m b -> m b
    

    然后你就可以看到类型匹配了。

    【讨论】:

    • 这听起来简单明了,谢谢。 =
    【解决方案2】:

    一些有用的概念在这里使用:

    1. 具有变量a 的任何类型都可以通过将a 的每个实例替换为任何其他类型t 来转换为不同的类型。因此,如果您有a -&gt; b -&gt; c 类型,则可以通过将b 替换为dc 分别替换为Int 来获得a -&gt; d -&gt; c 类型或a -&gt; b -&gt; Int 类型。
    2. 可以通过替换相互转换的任何两种类型都是等价的。例如,a -&gt; bc -&gt; d 是等价的(a ~ cb ~ d)。
    3. 如果t 类型可以转换为t' 类型,但t' 不能转换回t,那么我们说t' 是一个特化t。例如,a -&gt; aa -&gt; b 的特化。

    现在,有了这些非常有用的概念,您的问题的答案就很简单了:即使函数的“本机”类型不完全匹配,它们也是兼容的,因为它们可以被重写或专门化以获得精确匹配。 Matt Fenwick 的回答显示了针对这种情况的专业化。

    【讨论】:

      【解决方案3】:

      它试图将am b统一起来,并简单地决定a必须是m b,所以(=&lt;&lt;)的类型(假设a ~ m b)是Monad m =&gt; (mb -&gt; m b) -&gt; m (m b) -&gt; m b,并且一次你把它应用到id,你就剩下Monad m =&gt; m (m b) -&gt; m b

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-01-27
        • 2016-01-16
        • 1970-01-01
        • 2017-12-19
        • 1970-01-01
        • 2014-10-11
        • 2017-08-21
        相关资源
        最近更新 更多