, , , (, - , , ).
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ConstraintKinds #-}
import Data.Constraint
data AType
data BType
data F x y where
A :: a -> F AType a
B :: F BType a
type family ValidCombo x y :: Constraint where
ValidCombo BType ty2 = ty2 ~ AType
ValidCombo ty1 ty2 = ()
f :: ValidCombo ty1 ty2 => F ty1 a -> F ty2 a -> F ty1 a
f (A x) B = A x
f B (A _) = B
f (A _) (A x) = A x
f B B = ..., f B B. let z = f (f B (A 1)) B ( ).
, , F. ( , ). (AType BType) phantom F.
ValidCombo ( , , Haskell, ). () - , ( , , ). a ~ b a b (~ ) , . , ( F), :
data Tag = ATag | BTag
deriving Eq
getTag :: F a -> Tag
getTag (A _) = ATag
getTag B = BTag
validCombo :: F a -> F a -> Bool
validCombo B tag2 = (getTag tag2) == ATag
validCombo _ _ = True
( , " " .)
DataKinds, , F AType BType, ( ).
, , Maybe, @DirkyJerky, - (- ).
Haskell ( , , , ), , .