में अलग-अलग टाइप किए गए पैरामीटर का उपयोग नहीं कर सकते हैं Type Level Literals के साथ किसी भी प्रकार के प्रकार का उपयोग करके गैर खाली कंटेनर मानों (जैसे प्रेत प्रकारों के साथ) को भेदभाव करने के तरीके के रूप में खेलना।टाइप लेवल लिटलल्स - द्विआधारी फ़ंक्शन
यह अच्छी तरह से काम करता है। (आवश्यक GHC> = 7.6.1)
लेकिन एक द्विआधारी समारोह को परिभाषित करने की कोशिश कर (eq)
eq :: (Eq a) => TMaybe (sym :: Symbol) a -> TMaybe (sym :: Symbol) a -> Bool
है कि मूल्यों के विभिन्न समूहों मानते हैं, एक संकलन त्रुटि जब यह प्रयोग किया जाता है का संकेत:
प्रकार से मेल नहीं किया जा सका "Just"' with
"कुछ भी नहीं" '
{-# LANGUAGE DataKinds, KindSignatures, GADTs, FlexibleInstances #-}
import GHC.TypeLits
data TMaybe :: Symbol -> * -> * where
TNothing :: TMaybe "Nothing" a
TJust :: a -> TMaybe "Just" a
nonEmpty :: Maybe a -> TMaybe "Just" a
nonEmpty (Just x) = TJust x
nonEmpty Nothing = error "invalid nonEmpty data"
-- this fromJust rejects TNothing at compile time
fromJust :: (sym ~ "Just") => TMaybe (sym :: Symbol) a -> a
fromJust (TJust x) = x
tmbToMaybe :: TMaybe (sym :: Symbol) a -> Maybe a
tmbToMaybe TNothing = Nothing
tmbToMaybe (TJust x) = Just x
mbToTNothing Nothing = TNothing
mbToTJust (Just x) = TJust x
instance Eq a => Eq (TMaybe (sym :: Symbol) a) where
TNothing == TNothing = True
TJust x == TJust y = x == y
_ == _ = False -- useless, equal types required
instance Ord a => Ord (TMaybe (sym :: Symbol) a) where
compare TNothing TNothing = EQ
compare (TJust x) (TJust y) = Prelude.compare x y
compare TNothing _ = LT -- useless, equal types required
compare _ TNothing = GT -- useless, equal types required
instance Functor (TMaybe (sym :: Symbol)) where
fmap _ TNothing = TNothing
fmap f (TJust a) = TJust (f a)
instance Monad (TMaybe "Just") where
(TJust x) >>= k = k x
(TJust _) >> k = k
return = TJust
fail _ = error "can't fail to TNothing"
--------------------------
-- defining eq to admit parameter types with different symbol
eq :: (Eq a) => TMaybe (sym :: Symbol) a -> TMaybe (sym :: Symbol) a -> Bool
eq TNothing TNothing = True
eq (TJust x) (TJust y) = x == y
eq _ _ = False
---------------------------
-- Test
main = do
print $ fromJust $ TJust (5::Int) -- type-checks
-- print $ fromJust TNothing -- as expected, does not type-check
-- print $ TNothing == TJust (5::Int) -- as expected, does not type-check, types required equal at function def.
print $ TNothing `eq` TJust (5::Int) -- does not type-check either
धन्यवाद, इस प्रकार के सामान को छेड़छाड़ करने के साथ, मैंने 'sym' चर पर ध्यान नहीं दिया –