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

Haskell函数的部分应用,派生类型,haskell,Haskell,在GHCI prelude>中,使用:t查找函数类型: (.) :: (b -> c) -> (a -> b) -> a -> c (:) :: a -> [a] -> [a] ((.)(:)) :: (a -> b) -> a -> [b] -> [b] -- (what happened here?) 我理解单个函数的结果,但当部分应用时,我不理解 我在这一页上找到了一个答案,如何用代数方法来做。但是我在(:)上应用

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

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

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

((.)(:)) :: (a -> b) -> a -> [b] -> [b]   -- (what happened here?)
我理解单个函数的结果,但当部分应用时,我不理解

我在这一页上找到了一个答案,如何用代数方法来做。但是我在
(:)
上应用相同的方法时遇到问题

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


提前感谢。

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

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

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


如果在整个过程中应用此类型替换,则部分应用的
()
将丢失其第一个参数(它已被固定为
(:)
),并导致
(a->d)->a->([d]->[d])
,这相当于
(a->d)->[d]->[d]
(同样,通过正确的关联性):这是您从ghci获得的类型表达式。

要扩展@Riccardo的答案:

  • 类型签名的对应关系

    (b  ->       c     )       -- first argument of (.)
    (d  ->  ([d] -> [d])       --   corresponds to type of (:)
    
  • 替代品

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

  • 右结合性

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