封闭类型家族内的模式匹配

mon*_*ell 5 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) = ???
Run Code Online (Sandbox Code Playgroud)

我想根据CmpSymbolGHC.TypeLits 中的结果返回不同的类型 。感觉就像

Cmp (s1 ::: t1) (s2 ::: t2) = (CmpSymbol s1 s2 ~ LT) => Pre
Cmp (s1 ::: t1) (s2 ::: t2) = (CmpSymbol s1 s2 ~ GT) => Post
Run Code Online (Sandbox Code Playgroud)

应该工作,但它没有。有趣的是,这不是语法错误,而是抱怨它不友善。

我可以通过使用不可判定的实例和辅助函数以某种方式让它工作:

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
Run Code Online (Sandbox Code Playgroud)

但这感觉相当笨重,肯定有更好的方法吗?ghci 还说 即使是关闭的,:kind! Cmp ("a" ::: Int) ("a" ::: String)也有类型。这是为什么?我也看不到在这里处理普通课程的简单方法?如果的定义类似于Fun 'EQFunFun

class Fun2 o r
instance Fun2 LT Pre
instance Fun2 GT Post
Run Code Online (Sandbox Code Playgroud)

有没有办法以一种很好的方式与类型类交谈,或者我是否仅限于使用其他类型系列,例如Fun

use*_*038 2

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

不幸的是,没有办法LT -> Pre从像这样的类中获取类型函数Fun2.

你的例子很友善,Fun EQ因为你将CmpSymbol "a" "a"EQ传递给Fun. 它不只是给出错误的原因是类型族被尽可能晚地评估 - 这里你不要求它的“值”,Fun EQ所以还没有必要评估它。