Я пытаюсь создать статически типизированную систему авторизации и получить следующий рабочий фрагмент кода:
{-# LANGUAGE DataKinds, ScopedTypeVariables, TypeFamilies #-}
module Try where
import Data.Singletons.TH
data FeatureFlag = Feature1 | Feature2 deriving (Eq, Show)
$(genSingletons [''FeatureFlag])
type family Feature (f :: FeatureFlag) (fs :: [FeatureFlag]) where
Feature f '[] = 'False
Feature f (f:fs) = 'True
Feature f (q:fs) = Feature f fs
lockedFeatureAction :: (MonadIO (m fs), Feature 'Feature1 fs ~ 'True) => m fs ()
lockedFeatureaction = undefined
checkFeatureFlagsAndRun :: forall (fs :: [FeatureFlag]) . (SingI fs) => Proxy fs -> AppM fs () -> IO ()
checkFeatureFlagsAndRun = undefined
И вот как это привыкает:
ghci> checkFeatureFlagsAndRun (Proxy :: Proxy '[ 'Feature1]) lockedFeatureAction
Все хорошо, когда типы и звезды совпадают. Однако, если типы не совпадают, сообщение об ошибке классического Шерлока Холмса "whodunnit":
ghci> checkFeatureFlagsAndRun (Proxy :: Proxy '[ 'Feature2]) lockedFeatureAction
<interactive>:462:32: error:
• Couldn't match type ‘'False’ with ‘'True’
arising from a use of ‘lockedFeatureAction’
• In the second argument of ‘checkFeatureFlagsAndRun’, namely ‘lockedFeatureAction’
In the expression: checkFeatureFlagsAndRun (Proxy :: Proxy '[ 'Feature2]) lockedFeatureAction
In an equation for ‘it’: it = checkFeatureFlagsAndRun (Proxy :: Proxy '[ 'Feature2]) lockedFeatureAction
Я попытался найти и наткнулся на https://kcsongor.github.io/report-stuck-families/,, что говорит о TypeError
Я пытался использовать это так, но это не сработало:
type family Feature (f :: FeatureFlag) (fs :: [FeatureFlag]) where
Feature f '[] = TypeError "Could not satisfy FeatureFlag conditions"
Feature f (f:fs) = 'True
Feature f (q:fs) = Feature f fs
-- • Expected kind ‘ghc-prim-0.5.2.0:GHC.Types.Symbol -> Bool’,
-- but ‘TypeError’ has kind ‘*’
-- • In the type ‘TypeError "Could not satisfy FeatureFlag conditions"’
-- In the type family declaration for ‘Feature’
-- |
-- 19 | Feature f '[] = TypeError "Could not satisfy FeatureFlag conditions"
-- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Как правильно использовать TypeError
? В качестве альтернативы, есть ли другой способ получить лучшие сообщения об ошибках?