具有复合/多参数类型构造函数的Haskell类型签名

时间:2015-03-23 12:33:29

标签: haskell types polymorphism

我发现了这些类型的签名:

x :: a b -> Int
x f = 3

y :: a b c -> Int
y f = 3

z :: a b c d -> Int
z f = 3

> x [1] -- 3
> y (1, 2) -- 3
> z (1, 2, 3) -- 3

基本上:

  1. x仅接受包含1个或更多参数的类型构造函数的值。
  2. y只接受一个包含2个或更多参数的类型构造函数的值。
  3. z只接受一个包含3个或更多参数的类型构造函数的值。
  4. 它们是有效的,但我不确定它们的含义以及它们可用于什么。

    它们似乎与类型构造函数上的多型概念或多态相关,但是基于类型构造函数接受的许多参数强制执行不变量。

2 个答案:

答案 0 :(得分:8)

没有进一步的限制,这些类型是无用的 - 你无法用它们做任何事情,期望它们正确传递。但实际情况与签名a -> Int的情况相同:如果对a一无所知,那么你也无能为力!

然而,与例如toInteger :: Integral a => a -> Integer,为参数添加约束可以让你做一些事情。例如,

import Data.Foldable
import Prelude hiding (foldr)

x' :: (Foldable a, Integral b) => a b -> Integer
x' = foldr ((+) . toInteger) 0

通常情况下,如果您的表单类型为a b ... n o p q,那么a b ... p至少是Functor类的一个实例,通常也是ApplicativeMonad;有时候FoldableTraversableComonad;有时a b ... o将是Arrow ...这些约束允许您对复合类型做很多事情,而不知道您正在处理哪些特定类型构造函数。

答案 1 :(得分:0)

在研究了@leftaroundabout回答并在GHCI中进行实验后,我已经了解了复合类型。它们与应用类型的统一基于评估顺序和它们的类型变量的类型签名。评估顺序非常重要,a b c ~ (((a) b) c) a (b c)(a ((b) c)。这使得a b c匹配复合类型,其中a与类* -> * -> *的类型构造函数匹配,a b* -> *a b c与{{{ 1}}。

我在这个要点(https://gist.github.com/CMCDragonkai/2a1d3ecb67dcdabfc7e0)中用图表和GHCI代码完全解释了它(它对于堆栈溢出而言太长了)