Jest to niemożliwe w GHC przed 8.0, ale the (as of this writing) just-released GHC 8.0.1 dodać s wsparcie dla custom type errors.
Chodzi o to, że, podobnie jak funkcja error :: String -> a
zamieszkuje wszelkiego rodzaju z błędem na poziomie termin, mamy teraz, in GHC.TypeLits
, rodzinę typu
type family TypeError (msg :: ErrorMessage) :: k
zamieszkującą dowolny typ z błąd typu. Typ ErrorMessage
jest bardzo prosta:
data ErrorMessage = Text Symbol
| ShowType t
| ErrorMessage :<>: ErrorMessage
| ErrorMessage :$$: ErrorMessage
Konstruktor (:<>:)
łączy dwa komunikaty o błędach poziomo; konstruktor (:$$:)
łączy je w pionie. Pozostali dwaj konstruktorzy robią to, co mówią.
Tak więc w twoim przykładzie możesz wypełnić ostatni przypadek przy pomocy TypeError
; na przykład
type family Testf a where
Testf Char = IO()
Testf String = IO()
Testf a = TypeError ( Text "‘Testf’ didn't match"
:$$: Text "when applied to the type ‘"
:<>: ShowType a :<>: Text "’")
Następnie próbuje użyć pure()
w rodzaju Testf Int
zakończy się niepowodzeniem z błędem
....hs:19:12: error: …
• ‘Testf’ didn't match
when applied to the type ‘Int’
• In the expression: pure()
In an equation for ‘testfInt’: testfInt = pure()
Compilation failed.
Należy pamiętać, że przy definiowaniu
testfInt :: Testf Int
testfInt = pure()
poprawnie złamał, definiując
testfInt :: Testf Int
testfInt = undefined
(lub podobnie z testfInt = testfInt
) działało bez zarzutu.
Oto pełna przykładowy plik źródłowy:
{-# LANGUAGE UndecidableInstances, TypeFamilies, DataKinds, TypeOperators #-}
import GHC.TypeLits
type family Testf a where
Testf Char = IO()
Testf String = IO()
Testf a = TypeError ( Text "‘Testf’ didn't match"
:$$: Text "when applied to the type ‘"
:<>: ShowType a :<>: Text "’")
testfChar :: Testf Char
testfChar = putStrLn "Testf Char"
testfString :: Testf Char
testfString = putStrLn "Testf String"
-- Error here!
testfInt :: Testf Int
testfInt = putStrLn "Int"
GHC 8.0 oferuje coś takiego w 'TypeLits', ze szczególnym wsparciem typ sprawdzania uczynienia błędy wyglądać dobrze. – dfeuer
Dobre znalezisko, dodane odniesienie do tego. –