@@ -22,6 +22,7 @@ import Language.PureScript.Environment
2222import Language.PureScript.Errors
2323import Language.PureScript.Names
2424import Language.PureScript.Types
25+import Language.PureScript.TypeChecker (checkNewtype)
2526import qualified Language.PureScript.Constants as C
2627
2728-- | Elaborates deriving instance declarations by code generation.
@@ -44,14 +45,21 @@ deriveInstance mn ds (TypeInstanceDeclaration nm deps className tys@[ty] Derived
4445 , Just (Qualified mn' tyCon, args) <- unwrapTypeConstructor ty
4546 , mn == fromMaybe mn mn'
4647 = 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")
4849 , Just (Qualified mn' tyCon, _) <- unwrapTypeConstructor ty
4950 , mn == fromMaybe mn mn'
5051 = 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")
5253 , Just (Qualified mn' tyCon, _) <- unwrapTypeConstructor ty
5354 , mn == fromMaybe mn mn'
5455 = 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'
60+ = do
61+ (inst, actualUnwrappedTy) <- deriveNewtype mn ds tyCon unwrappedTy
62+ return $ TypeInstanceDeclaration nm deps className [wrappedTy, actualUnwrappedTy] (ExplicitInstance inst)
5563deriveInstance _ _ (TypeInstanceDeclaration _ _ className tys DerivedInstance)
5664 = throwError . errorMessage $ CannotDerive className tys
5765deriveInstance mn ds (TypeInstanceDeclaration nm deps className tys@(_ : _) NewtypeInstance)
@@ -100,6 +108,15 @@ dataMaybe = ModuleName [ ProperName "Data", ProperName "Maybe" ]
100108typesProxy :: ModuleName
101109typesProxy = ModuleName [ ProperName "Type", ProperName "Proxy" ]
102110
111+dataEq :: ModuleName
112+dataEq = ModuleName [ ProperName "Data", ProperName "Eq" ]
113+
114+dataOrd :: ModuleName
115+dataOrd = ModuleName [ ProperName "Data", ProperName "Ord" ]
116+
117+dataNewtype :: ModuleName
118+dataNewtype = ModuleName [ ProperName "Data", ProperName "Newtype" ]
119+
103120deriveGeneric
104121 :: forall m. (MonadError MultipleErrors m, MonadSupply m)
105122 => ModuleName
@@ -290,7 +307,7 @@ deriveEq mn ds tyConNm = do
290307 preludeConj = App . App (Var (Qualified (Just (ModuleName [ProperName "Data", ProperName "HeytingAlgebra"])) (Ident C.conj)))
291308
292309 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)))
294311
295312 addCatch :: [CaseAlternative] -> [CaseAlternative]
296313 addCatch xs
@@ -360,7 +377,7 @@ deriveOrd mn ds tyConNm = do
360377 orderingBinder name = ConstructorBinder (orderingName name) []
361378
362379 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)))
364381
365382 mkCtorClauses :: ((ProperName 'ConstructorName, [Type]), Bool) -> m [CaseAlternative]
366383 mkCtorClauses ((ctorName, tys), isLast) = do
@@ -404,6 +421,47 @@ deriveOrd mn ds tyConNm = do
404421 $ decomposeRec rec
405422 toOrdering l r _ = ordCompare l r
406423
424+deriveNewtype
425+ :: forall m
426+ . (MonadError MultipleErrors m, MonadSupply m)
427+ => ModuleName
428+ -> [Declaration]
429+ -> ProperName 'TypeName
430+ -> Type
431+ -> m ([Declaration], Type)
432+deriveNewtype mn ds tyConNm unwrappedTy = do
433+ checkIsWildcard unwrappedTy
434+ go =<< findTypeDecl tyConNm ds
435+ where
436+
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"
445+ let inst =
446+ [ ValueDeclaration (Ident "wrap") Public [] $ Right $
447+ Constructor (Qualified (Just mn) ctorName)
448+ , ValueDeclaration (Ident "unwrap") Public [] $ Right $
449+ lamCase wrappedIdent
450+ [ CaseAlternative
451+ [ConstructorBinder (Qualified (Just mn) ctorName) [VarBinder unwrappedIdent]]
452+ (Right (Var (Qualified Nothing unwrappedIdent)))
453+ ]
454+ ]
455+ return (inst, ty)
456+ go (PositionedDeclaration _ _ d) = go d
457+ go _ = internalError "deriveNewtype go: expected DataDeclaration"
458+
459+ checkIsWildcard :: Type -> m ()
460+ checkIsWildcard (TypeWildcard _) =
461+ return ()
462+ checkIsWildcard _ =
463+ throwError . errorMessage $ NonWildcardNewtypeInstance tyConNm
464+
407465findTypeDecl
408466 :: (MonadError MultipleErrors m)
409467 => ProperName 'TypeName