大量の GHC 拡張機能を使用するこのコード スニペットがあります。
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
import GHC.Exts (Constraint)
data HList :: [*] -> * where
Nil :: HList '[]
Cons :: a -> HList l -> HList (a ': l)
type family All (p :: * -> Constraint) (xs :: HList [*]) :: Constraint where
All p Nil = ()
All p (Cons x xs) = (p x, All p xs)
GHC は次のように訴えています。
‘HList’ of kind ‘[*] -> *’ is not promotable
In the kind ‘HList [*]’
HList
種類を昇格できないのはなぜですか? GHC7.8.2
とを使用しても同じエラーが発生します7.11
。
もちろん、ビルトインを使用しても'[]
問題なく動作します。
type family All (p :: * -> Constraint) (xs :: [*]) :: Constraint where
All p '[] = ()
All p (x ': xs) = (p x, All p xs)
実際には追加がサポートされており、次のようになっているため、HList
代わりに自分のものを使用したいと思います。'[]
HList
type family (:++:) (xs :: [*]) (ys :: [*]) where
'[] :++: ys = ys
xs :++: '[] = xs
(x ': xs) :++: ys = x ': (xs :++: ys)
data HList :: [*] -> * where
Nil :: HList '[]
Cons :: a -> HList l -> HList (a ': l)
App :: Hlist a -> HList b -> HList (a :++: b)
EDIT:主な目標は、GHCに推論させることです
(All p xs, All p ys) ==> All p (xs :++: ys)
書けるように
data Dict :: Constraint -> * where
Dict :: c => Dict c
witness :: Dict (All p xs) -> Dict (All p ys) -> Dict (All p (xs :++: ys))
witness Dict Dict = Dict
型レベルのリストを追加するための明示的な表現を追加することが、これを達成するのに役立つことを願っていました。GHCに上記のことを納得させる別の方法はありますか?