@@ -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
0 commit comments