我无法尝试使用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
?
答案 0 :(得分:2)
这确实是唯一的方法,虽然我想定义一些可重用的类型函数(==
和If
),但在你的情况下它会变成If (CmpSymbol s1 s2 == LT) Pre Post
。
很遗憾,无法从像LT -> Pre
Fun2.
的类型函数
您的示例有Fun EQ
种,因为CmpSymbol "a" "a"
为EQ
,您将其传递给Fun
。它不仅仅是一个错误的原因是类型系列被评估为尽可能晚 - 在这里你不要求Fun EQ
的“值”,所以没有必要对它进行评估。