haskell - 在 Haskell 中查找组合函数的类型

标签 haskell types function-definition

假设我在 Haskell 中有以下功能:compose2 = (.) . (.)我将如何找到这个函数的类型?由于有多种组合,我在试图确定此函数的类型时遇到困难。
我知道我可以使用 :t compose2获取类型。但是,我想知道如何在没有计算机帮助的情况下做到这一点。我应该采取哪些步骤来查找类型?

最佳答案

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

compose2 = (.)2 .1 (.)3
这样更容易引用一些函数。我们还可以将其转换为更规范的形式,例如:
compose2 = ((.)1 (.)2) (.)3
所以现在我们可以开始推导函数类型了。我们知道(.)有类型 (.) :: (b -> c) -> (a -> b) -> a -> c ,或更规范的 (.) :: (b -> c) -> ((a -> b) -> (a -> c)) .由于类型变量不是“全局的”,因此我们可以为类型变量赋予树函数不同的名称:
(.)1 :: (b -> c) -> ((a -> b) -> (a -> c))
(.)2 :: (e -> f) -> ((d -> e) -> (d -> f))
(.)3 :: (h -> i) -> ((g -> h) -> (g -> i))
所以现在我们已经给不同的组合函数一个签名,我们可以开始派生类型。
我们知道(.)2是具有 (.)1 的函数应用程序的参数, 所以这意味着参数的类型 (b -> c)与类型相同 (e -> f) -> ((d -> e) -> (d -> f)) ,因此 b ~ (e -> f) , 和 c ~ ((d -> e) -> (d -> f)) .
我们进一步知道(.)1的“第二个”参数的类型。与(.)3的类型相同, 所以 (a -> b) ~ ((h -> i) -> ((g -> h) -> (g -> i))) ,因此 a ~ (h -> i) , 和 b ~ ((g -> h) -> (g -> i)) ,因此 (.)1 的“返回类型” , 即 (a -> c)因此可以专门用于:
((.)1 (.)2) (.)3 :: a -> c
a ~ (h -> i) , 和 c ~ (d -> e) -> (d -> f) :
((.)1 (.)2) (.)3 :: (h -> i) -> ((d -> > e) -> (d > f))
我们知道b等同于 b ~ (e -> f)b ~ ((g -> h) -> (g -> i)) ,所以这意味着 e ~ (g -> h) , 和 f ~ (g -> i) ,因此我们可以进一步将签名特化为:
((.)1 (.)2) (.)3 :: (h -> i) -> ((d -> (g -> h)) -> (d -> (g -> i)))
这是一种更详细的形式:
(.)2 .1 (.)3 :: (h -> i) -> (d -> g -> h) -> d -> g -> i
如果我们自动派生类型,我们得到:
Prelude> :t (.) . (.)
(.) . (.) :: (b -> c) -> (a1 -> a -> b) -> a1 -> a -> c
如果我们因此替换 bh , ci , a1dag ,我们得到相同的类型。

关于haskell - 在 Haskell 中查找组合函数的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65050490/

相关文章:

Java数据类型问题

c - 我什么时候可以不用声明带有签名的 int?

比较字符串的结尾

c++ - 错误 lnk2005 已在 .obj 中定义

haskell - Yesod 重定向方法 GET PUT DELETE 哪一个?

html - Pandoc 忽略 Markdown-Headlines

.net - 是否有一个属性来限制自定义属性可能适用的类型?

c - 在 C 中使用指针时出现地址边界错误

performance - 拆箱四元组向量中的装箱值

scala - "world"在函数式编程世界中意味着什么?