Haskell部分应用函数,派生类型

时间:2012-04-05 14:30:19

标签: haskell

GHCI前奏> using: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 ?我在此页面上找到了答案,如何以代数方式执行此操作。但是我在((.)(:))上使用相同的方法时遇到了问题。

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

提前致谢。

2 个答案:

答案 0 :(得分:9)

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

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

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

(.) (:)部分将(:)应用于(.),仅提供其第一个参数。这意味着(.)的第一个参数(b -> c)(d -> ([d] -> [d]))实例化,b == dc == ([d] -> [d])(请记住{{1}是关联的。)

如果在整个事物中应用此类型替换,则会得到部分应用的->丢失其第一个参数(已修复为(.))并导致(:),这相当于(a -> d) -> a -> ([d] -> [d])(再次,通过右关联性):这是你从ghci得到的类型表达式。

答案 1 :(得分:6)

扩展@ 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]