封闭式家庭内的模式匹配

时间:2014-05-27 18:37:47

标签: haskell type-families

我无法尝试使用GHC 7.8的新封闭式家庭功能 我希望找到一种很好的方法来分类类型构造。

我有类似

的东西
data (:::) :: Symbol -> * -> * where

data Result = Pre | Post | Match

type family Cmp a b :: Result where
    Cmp (s ::: t) (s ::: t) = Match
    Cmp (s1 ::: t1) (s2 ::: t2) = ???

我希望根据结果返回不同的类型 GHC.TypeLits中的CmpSymbol。感觉像是

Cmp (s1 ::: t1) (s2 ::: t2) = (CmpSymbol s1 s2 ~ LT) => Pre
Cmp (s1 ::: t1) (s2 ::: t2) = (CmpSymbol s1 s2 ~ GT) => Post

应该有效,但事实并非如此。有趣的是,它不是语法错误,而是 而是投诉它是不适当的。

我可以通过使用不可判定的实例和a来以某种方式使其工作 辅助功能:

type family Cmp a b :: Result where
    Cmp (s ::: t) (s ::: t) = Match
    Cmp (s1 ::: t1) (s2 ::: t2) = Fun (CmpSymbol s1 s2)

type family Fun r :: Result where
    Fun LT = Pre
    Fun GT = Post

但这感觉相当笨重,肯定有更好的方法吗? ghci也说 :kind! Cmp ("a" ::: Int) ("a" ::: String)之类的内容类型Fun 'EQ 即使Fun已关闭。这是为什么?我也看不到一个简单的方法 和普通班一起工作?如果Fun的定义是什么,该怎么办? 像

class Fun2 o r
instance Fun2 LT Pre
instance Fun2 GT Post

有没有办法以一种很好的方式与类型类进行对话,或者我只限于 使用其他类型的家庭,如Fun

1 个答案:

答案 0 :(得分:2)

这确实是唯一的方法,虽然我想定义一些可重用的类型函数(==If),但在你的情况下它会变成If (CmpSymbol s1 s2 == LT) Pre Post

很遗憾,无法从像LT -> Pre

这样的类中获取类型Fun2.的类型函数

您的示例有Fun EQ种,因为CmpSymbol "a" "a"EQ,您将其传递给Fun。它不仅仅是一个错误的原因是类型系列被评估为尽可能晚 - 在这里你不要求Fun EQ的“值”,所以没有必要对它进行评估。