@@ -22,6 +22,7 @@ import Language.PureScript.Environment
22import Language.PureScript.Errors
22import Language.PureScript.Errors
23import Language.PureScript.Names
23import Language.PureScript.Names
24import Language.PureScript.Types
24import Language.PureScript.Types
25+import Language.PureScript.TypeChecker (checkNewtype)
25import qualified Language.PureScript.Constants as C
26import qualified Language.PureScript.Constants as C
27-- | Elaborates deriving instance declarations by code generation.
28-- | Elaborates deriving instance declarations by code generation.
@@ -44,14 +45,21 @@ deriveInstance mn ds (TypeInstanceDeclaration nm deps className tys@[ty] Derived
44 , Just (Qualified mn' tyCon, args) <- unwrapTypeConstructor ty
45 , Just (Qualified mn' tyCon, args) <- unwrapTypeConstructor ty
45 , mn == fromMaybe mn mn'
46 , mn == fromMaybe mn mn'
46 = TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveGeneric mn ds tyCon args
47 = TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveGeneric mn ds tyCon args
47− | className == Qualified (Just (ModuleName [ ProperName "Data", ProperName "Eq" ])) (ProperName "Eq")
48+ | className == Qualified (Just dataEq) (ProperName "Eq")
48 , Just (Qualified mn' tyCon, _) <- unwrapTypeConstructor ty
49 , Just (Qualified mn' tyCon, _) <- unwrapTypeConstructor ty
49 , mn == fromMaybe mn mn'
50 , mn == fromMaybe mn mn'
50 = TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveEq mn ds tyCon
51 = TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveEq mn ds tyCon
51− | className == Qualified (Just (ModuleName [ ProperName "Data", ProperName "Ord" ])) (ProperName "Ord")
52+ | className == Qualified (Just dataOrd) (ProperName "Ord")
52 , Just (Qualified mn' tyCon, _) <- unwrapTypeConstructor ty
53 , Just (Qualified mn' tyCon, _) <- unwrapTypeConstructor ty
53 , mn == fromMaybe mn mn'
54 , mn == fromMaybe mn mn'
54 = TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveOrd mn ds tyCon
55 = TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveOrd mn ds tyCon
56+deriveInstance mn ds (TypeInstanceDeclaration nm deps className [wrappedTy, unwrappedTy] DerivedInstance)
57+ | className == Qualified (Just dataNewtype) (ProperName "Newtype")
58+ , Just (Qualified mn' tyCon, _) <- unwrapTypeConstructor wrappedTy
59+ , mn == fromMaybe mn mn'
61+ (inst, actualUnwrappedTy) <- deriveNewtype mn ds tyCon unwrappedTy
62+ return $ TypeInstanceDeclaration nm deps className [wrappedTy, actualUnwrappedTy] (ExplicitInstance inst)
55deriveInstance _ _ (TypeInstanceDeclaration _ _ className tys DerivedInstance)
63deriveInstance _ _ (TypeInstanceDeclaration _ _ className tys DerivedInstance)
56 = throwError . errorMessage $ CannotDerive className tys
64 = throwError . errorMessage $ CannotDerive className tys
57deriveInstance mn ds (TypeInstanceDeclaration nm deps className tys@(_ : _) NewtypeInstance)
65deriveInstance mn ds (TypeInstanceDeclaration nm deps className tys@(_ : _) NewtypeInstance)
@@ -100,6 +108,15 @@ dataMaybe = ModuleName [ ProperName "Data", ProperName "Maybe" ]
100typesProxy :: ModuleName
108typesProxy :: ModuleName
101typesProxy = ModuleName [ ProperName "Type", ProperName "Proxy" ]
109typesProxy = ModuleName [ ProperName "Type", ProperName "Proxy" ]
112+dataEq = ModuleName [ ProperName "Data", ProperName "Eq" ]
114+dataOrd :: ModuleName
115+dataOrd = ModuleName [ ProperName "Data", ProperName "Ord" ]
117+dataNewtype :: ModuleName
118+dataNewtype = ModuleName [ ProperName "Data", ProperName "Newtype" ]
103deriveGeneric
120deriveGeneric
104 :: forall m. (MonadError MultipleErrors m, MonadSupply m)
121 :: forall m. (MonadError MultipleErrors m, MonadSupply m)
105 => ModuleName
122 => ModuleName
@@ -290,7 +307,7 @@ deriveEq mn ds tyConNm = do
290 preludeConj = App . App (Var (Qualified (Just (ModuleName [ProperName "Data", ProperName "HeytingAlgebra"])) (Ident C.conj)))
307 preludeConj = App . App (Var (Qualified (Just (ModuleName [ProperName "Data", ProperName "HeytingAlgebra"])) (Ident C.conj)))
292 preludeEq :: Expr -> Expr -> Expr
309 preludeEq :: Expr -> Expr -> Expr
293− preludeEq = App . App (Var (Qualified (Just (ModuleName [ProperName "Data", ProperName "Eq"])) (Ident C.eq)))
310+ preludeEq = App . App (Var (Qualified (Just dataEq) (Ident C.eq)))
295 addCatch :: [CaseAlternative] -> [CaseAlternative]
312 addCatch :: [CaseAlternative] -> [CaseAlternative]
296 addCatch xs
313 addCatch xs
@@ -360,7 +377,7 @@ deriveOrd mn ds tyConNm = do
360 orderingBinder name = ConstructorBinder (orderingName name) []
377 orderingBinder name = ConstructorBinder (orderingName name) []
362 ordCompare :: Expr -> Expr -> Expr
379 ordCompare :: Expr -> Expr -> Expr
363− ordCompare = App . App (Var (Qualified (Just (ModuleName [ProperName "Data", ProperName "Ord"])) (Ident C.compare)))
380+ ordCompare = App . App (Var (Qualified (Just dataOrd) (Ident C.compare)))
365 mkCtorClauses :: ((ProperName 'ConstructorName, [Type]), Bool) -> m [CaseAlternative]
382 mkCtorClauses :: ((ProperName 'ConstructorName, [Type]), Bool) -> m [CaseAlternative]
366 mkCtorClauses ((ctorName, tys), isLast) = do
383 mkCtorClauses ((ctorName, tys), isLast) = do
@@ -404,6 +421,47 @@ deriveOrd mn ds tyConNm = do
404 $ decomposeRec rec
421 $ decomposeRec rec
405 toOrdering l r _ = ordCompare l r
422 toOrdering l r _ = ordCompare l r
426+ . (MonadError MultipleErrors m, MonadSupply m)
429+ -> ProperName 'TypeName
431+ -> m ([Declaration], Type)
432+deriveNewtype mn ds tyConNm unwrappedTy = do
433+ checkIsWildcard unwrappedTy
434+ go =<< findTypeDecl tyConNm ds
437+ go :: Declaration -> m ([Declaration], Type)
438+ go (DataDeclaration Data name _ _) =
439+ throwError . errorMessage $ CannotDeriveNewtypeForData name
440+ go (DataDeclaration Newtype name _ dctors) = do
441+ checkNewtype name dctors
442+ let (ctorName, [ty]) = head dctors
443+ wrappedIdent <- freshIdent "n"
444+ unwrappedIdent <- freshIdent "a"
446+ [ ValueDeclaration (Ident "wrap") Public [] $ Right $
447+ Constructor (Qualified (Just mn) ctorName)
448+ , ValueDeclaration (Ident "unwrap") Public [] $ Right $
449+ lamCase wrappedIdent
451+ [ConstructorBinder (Qualified (Just mn) ctorName) [VarBinder unwrappedIdent]]
452+ (Right (Var (Qualified Nothing unwrappedIdent)))
456+ go (PositionedDeclaration _ _ d) = go d
457+ go _ = internalError "deriveNewtype go: expected DataDeclaration"
459+ checkIsWildcard :: Type -> m ()
460+ checkIsWildcard (TypeWildcard _) =
463+ throwError . errorMessage $ NonWildcardNewtypeInstance tyConNm
407findTypeDecl
465findTypeDecl
408 :: (MonadError MultipleErrors m)
466 :: (MonadError MultipleErrors m)
409 => ProperName 'TypeName
467 => ProperName 'TypeName