@@ -11,6 +11,7 @@ module Language.PureScript.Sugar.TypeClasses
11
11
import Prelude
12
12
13
13
import Control.Arrow (first , second )
14
+ import Control.Monad (unless )
14
15
import Control.Monad.Error.Class (MonadError (.. ))
15
16
import Control.Monad.State (MonadState (.. ), StateT , evalStateT , modify )
16
17
import Control.Monad.Supply.Class (MonadSupply )
@@ -336,26 +337,33 @@ typeInstanceDictionaryDeclaration sa@(ss, _) name mn deps className tys decls =
336
337
337
338
let declaredMembers = S. fromList $ mapMaybe declIdent decls
338
339
339
- case filter (\ (ident, _) -> not $ S. member ident declaredMembers) memberTypes of
340
- hd : tl -> throwError . errorMessage' ss $ MissingClassMember (hd NEL. :| tl)
341
- [] -> do
342
- -- Create values for the type instance members
343
- members <- zip (map typeClassMemberName decls) <$> traverse (memberToValue memberTypes) decls
344
-
345
- -- Create the type of the dictionary
346
- -- The type is a record type, but depending on type instance dependencies, may be constrained.
347
- -- The dictionary itself is a record literal.
348
- superclassesDicts <- for typeClassSuperclasses $ \ (Constraint _ superclass _ suTyArgs _) -> do
349
- let tyArgs = map (replaceAllTypeVars (zip (map fst typeClassArguments) tys)) suTyArgs
350
- pure $ Abs (VarBinder ss UnusedIdent ) (DeferredDictionary superclass tyArgs)
351
- let superclasses = superClassDictionaryNames typeClassSuperclasses `zip` superclassesDicts
352
-
353
- let props = Literal ss $ ObjectLiteral $ map (first mkString) (members ++ superclasses)
354
- dictTy = foldl srcTypeApp (srcTypeConstructor (fmap (coerceProperName . dictTypeName) className)) tys
355
- constrainedTy = quantify (foldr srcConstrainedType dictTy deps)
356
- dict = App (Constructor ss (fmap (coerceProperName . dictTypeName) className)) props
357
- result = ValueDecl sa name Private [] [MkUnguarded (TypedValue True dict constrainedTy)]
358
- return result
340
+ -- Instance declarations with a Fail constraint are unreachable code, so
341
+ -- we allow them to be empty.
342
+ let unreachable = any ((C. Fail == ) . constraintClass) deps && null decls
343
+
344
+ unless unreachable $
345
+ case filter (\ (ident, _) -> not $ S. member ident declaredMembers) memberTypes of
346
+ hd : tl -> throwError . errorMessage' ss $ MissingClassMember (hd NEL. :| tl)
347
+ [] -> pure ()
348
+
349
+ -- Create values for the type instance members
350
+ members <- zip (map typeClassMemberName decls) <$> traverse (memberToValue memberTypes) decls
351
+
352
+ -- Create the type of the dictionary
353
+ -- The type is a record type, but depending on type instance dependencies, may be constrained.
354
+ -- The dictionary itself is a record literal (unless unreachable, in which case it's undefined).
355
+ superclassesDicts <- for typeClassSuperclasses $ \ (Constraint _ superclass _ suTyArgs _) -> do
356
+ let tyArgs = map (replaceAllTypeVars (zip (map fst typeClassArguments) tys)) suTyArgs
357
+ pure $ Abs (VarBinder ss UnusedIdent ) (DeferredDictionary superclass tyArgs)
358
+ let superclasses = superClassDictionaryNames typeClassSuperclasses `zip` superclassesDicts
359
+
360
+ let props = Literal ss $ ObjectLiteral $ map (first mkString) (members ++ superclasses)
361
+ dictTy = foldl srcTypeApp (srcTypeConstructor (fmap (coerceProperName . dictTypeName) className)) tys
362
+ constrainedTy = quantify (foldr srcConstrainedType dictTy deps)
363
+ dict = App (Constructor ss (fmap (coerceProperName . dictTypeName) className)) props
364
+ mkTV = if unreachable then TypedValue False (Var nullSourceSpan C. I_undefined ) else TypedValue True dict
365
+ result = ValueDecl sa name Private [] [MkUnguarded (mkTV constrainedTy)]
366
+ return result
359
367
360
368
where
361
369
0 commit comments