【问题标题】:Haskell partial application of functions, deriving typesHaskell函数的部分应用,派生类型
【发布时间】:2012-04-05 14:30:18
【问题描述】:

在 GHCI prelude> 中使用 :t 来查找函数的类型:

(.) :: (b -> c) -> (a -> b) -> a -> c

(:) :: a -> [a] -> [a]

((.)(:)) :: (a -> b) -> a -> [b] -> [b]   -- (what happened here?)

我了解单个函数的结果,但当部分应用时我不了解。

what is the type of map map ?我在此页面上找到了答案,如何以代数方式执行此操作。但我在((.)(:)) 上应用相同的方法时遇到问题。

想知道((.)(:))的类型有什么方法?有没有一种思维方式可以用于函数的任何部分应用?

提前致谢。

【问题讨论】:

    标签: haskell


    【解决方案1】:

    当您想要推断部分应用程序的类型时,最好的做法是从构建块的最通用类型开始,并在您正在编写的类型之间搜索匹配项。 让我通过向您描述我对您正在搜索的类型所遵循的推理来更清楚地说明这一点。

    首先,让我们重命名(:)的类型变量以避免混淆:

    (.) :: (b -> c) -> (a -> b) -> a -> c
    (:) :: d -> [d] -> [d]
    

    (.) (:) 部分地将(:) 应用于(.),仅提供其第一个参数。这意味着(.) 的第一个参数,即(b -> c) 类型,被实例化为(d -> ([d] -> [d])),具有b == dc == ([d] -> [d])(请记住-> 是右结合的)。

    如果你在整个事情中应用这种类型替换,你会得到部分应用的(.)会丢失它的第一个参数(它已被固定为(:))并导致(a -> d) -> a -> ([d] -> [d]),这相当于@987654335 @(同样,通过右关联性):这是您从 ghci 获得的类型表达式。

    【讨论】:

      【解决方案2】:

      扩展@Riccardo 的回答:

      1. 类型签名的对应

        (b  ->       c     )       -- first argument of (.)
        (d  ->  ([d] -> [d])       --   corresponds to type of (:)
        
      2. 替换

        (a -> b) -> a ->      c    -- rest of (.)'s type, minus first argument
        

        (a -> d) -> a -> ([d] -> [d])
        
      3. 右结合

        (a -> d) -> a -> [d] -> [d]
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多