【问题标题】:Finding the type of a composition function in Haskell在 Haskell 中查找组合函数的类型
【发布时间】:2021-03-11 00:18:27
【问题描述】:

假设我在 Haskell 中有以下函数:

compose2 = (.) . (.)

我将如何查找此函数的类型?由于有多种组合,我在试图确定这个函数的类型时遇到了困难。

我知道我可以使用:t compose2 来获取类型。但是,我想知道如何在没有计算机帮助的情况下做到这一点。我应该采取哪些步骤来找到类型?

【问题讨论】:

标签: haskell types function-definition


【解决方案1】:

如果我们首先给组合函数一个更唯一的标识符可能会有所帮助,例如:

compose2 = (.)<sub>2</sub> .<sub>1</sub> (.)<sub>3</sub>

这样更容易引用某些函数。我们还可以将其转换为更规范的形式,例如:

compose2 = ((.)<sub>1</sub> (.)<sub>2</sub>) (.)<sub>3</sub>

所以现在我们可以开始推导函数类型了。我们知道(.) 的类型为(.) :: (b -&gt; c) -&gt; (a -&gt; b) -&gt; a -&gt; c,或更规范的(.) :: (b -&gt; c) -&gt; ((a -&gt; b) -&gt; (a -&gt; c))。由于类型变量不是“全局的”,因此我们可以为类型变量赋予树函数不同的名称:

(.)1 :: (b -> c) -> ((a -> b) -> (a -> c))
(.)2 :: (e -> f) -> ((d -> e) -> (d -> f))
(.)3 :: (h -> i) -> ((g -> h) -> (g -> i))

现在我们已经给不同的组合函数一个签名,我们可以开始派生类型了。

我们知道(.)<sub>2</sub>是带有(.)<sub>1</sub>的函数应用的参数,也就是说(b -&gt; c)的参数类型与(e -&gt; f) -&gt; ((d -&gt; e) -&gt; (d -&gt; f))的类型相同,因此b ~ (e -&gt; f),和c ~ ((d -&gt; e) -&gt; (d -&gt; f))

我们进一步知道(.)<sub>1</sub>的“第二”参数的类型与(.)<sub>3</sub>的类型相同,所以(a -&gt; b) ~ ((h -&gt; i) -&gt; ((g -&gt; h) -&gt; (g -&gt; i))),因此a ~ (h -&gt; i),和b ~ ((g -&gt; h) -&gt; (g -&gt; i)),因此“返回(.)<sub>1</sub> 的类型”,即 (a -&gt; c) 因此可以专门用于:

((.)<sub>1</sub> (.)<sub>2</sub>) (.)<sub>3</sub> :: a -&gt; c

因为a ~ (h -&gt; i),和c ~ (d -&gt; e) -&gt; (d -&gt; f)

((.)<sub>1</sub> (.)<sub>2</sub>) (.)<sub>3</sub> :: (h -&gt; i) -&gt; ((d -&gt; &gt; e) -&gt; (d &gt; f))

我们知道b 等同于b ~ (e -&gt; f)b ~ ((g -&gt; h) -&gt; (g -&gt; i)),因此这意味着e ~ (g -&gt; h)f ~ (g -&gt; i),因此我们可以进一步将签名专门化为:

((.)<sub>1</sub> (.)<sub>2</sub>) (.)<sub>3</sub> :: (h -&gt; i) -&gt; ((d -&gt; (g -&gt; h)) -&gt; (d -&gt; (g -&gt; i)))

这是一种更详细的形式:

(.)<sub>2</sub> .<sub>1</sub> (.)<sub>3</sub> :: (h -&gt; i) -&gt; (d -&gt; g -&gt; h) -&gt; d -&gt; g -&gt; i

如果我们自动推导出类型,我们会得到:

Prelude> :t (.) . (.)
(.) . (.) :: (b -> c) -> (a1 -> a -> b) -> a1 -> a -> c

如果我们用h替换b,用i替换c,用d替换a1,用a替换g,我们得到相同的类型。

【讨论】:

  • 非常感谢您的全面回答!我现在可以自己获取类型了:)
猜你喜欢
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 2017-12-04
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多