你能在Haskell的类型级别进行模式匹配吗?

时间:2014-08-15 15:26:04

标签: haskell types algebraic-data-types

基本上,我想要的是一个函数类型(a - > b - > c - > ...),并返回该函数类型的所有右子集类型的列表,例如,让我们调用这个函数f:

x = f (a -> b -> c)

x
> [a -> b -> c, b -> c, c]

这应该适用于多态类型,如我的例子和具体的函数类型。

如果您可以在类型级别上使用函数类型进行模式匹配,那么这将是相对简单的:

g (x -> xs) = xs
g (x) = x

用作上面构造f的效用函数,并且函数类型上的模式匹配类似于在列表上进行模式匹配。

1 个答案:

答案 0 :(得分:14)

您正在寻找封闭式家庭:

{-# LANGUAGE TypeFamilies #-}
type family F a where
    F (x -> xs) = xs
    F x         = x

要完全回答您的问题,我们还需要DataKinds来获取类型级别列表:

{-# LANGUAGE TypeFamilies, TypeOperators, DataKinds #-}

type family F a :: [*] where
    F (x -> xs) = (x -> xs) ': (F xs)
    F x         = '[x]

单引号表示我们在类型级别使用那些(列表)构造函数。

我们可以看到,这给出了GHCi中:kind!命令的预期结果

λ> :kind! F (Int -> Float -> Double)
F (Int -> Float -> Double) :: [*]
= '[Int -> Float -> Double, Float -> Double, Double]

请注意,F的退货类型为[*]。这意味着为了使用这些结果,您需要以某种方式从列表中提取它们。唯一具有有人居住类型的是*(嗯,#)。

未标记的和类型

关于完整背景: 您可以通过分别使用来自Elem(==)的类型级别(||)Data.Type.Equality制作Data.Type.Bool类型系列来制作类似无标记和类型的内容