Skip to content

Commit d5d0adf

Browse files
committed
Ord deriving
1 parent 469b5ae commit d5d0adf

File tree

2 files changed

+64
-4
lines changed

2 files changed

+64
-4
lines changed

src/Language/PureScript/Constants.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ eq = "eq"
9898
notEq :: String
9999
notEq = "notEq"
100100

101+
compare :: String
102+
compare = "compare"
103+
101104
(&&) :: String
102105
(&&) = "&&"
103106

src/Language/PureScript/Sugar/TypeClasses/Deriving.hs

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,14 @@ deriveInstance mn ds (TypeInstanceDeclaration nm deps className tys@[ty] Derived
5050
, Just (Qualified mn' tyCon, args) <- unwrapTypeConstructor ty
5151
, mn == fromMaybe mn mn'
5252
= TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveGeneric mn ds tyCon args
53-
| className == Qualified (Just (ModuleName [ ProperName "Prelude" ])) eq
53+
| className == Qualified (Just (ModuleName [ ProperName "Prelude" ])) (ProperName "Eq")
5454
, Just (Qualified mn' tyCon, _) <- unwrapTypeConstructor ty
5555
, mn == fromMaybe mn mn'
5656
= TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveEq mn ds tyCon
57+
| className == Qualified (Just (ModuleName [ ProperName "Prelude" ])) (ProperName "Ord")
58+
, Just (Qualified mn' tyCon, _) <- unwrapTypeConstructor ty
59+
, mn == fromMaybe mn mn'
60+
= TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveOrd mn ds tyCon
5761
deriveInstance _ _ (TypeInstanceDeclaration _ _ className tys DerivedInstance)
5862
= throwError . errorMessage $ CannotDerive className tys
5963
deriveInstance mn ds (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> deriveInstance mn ds d
@@ -77,9 +81,6 @@ dataMaybe = ModuleName [ ProperName "Data", ProperName "Maybe" ]
7781
typesProxy :: ModuleName
7882
typesProxy = ModuleName [ ProperName "Type", ProperName "Proxy" ]
7983

80-
eq :: ProperName 'ClassName
81-
eq = ProperName "Eq"
82-
8384
deriveGeneric
8485
:: forall m. (Functor m, MonadError MultipleErrors m, MonadSupply m)
8586
=> ModuleName
@@ -265,6 +266,62 @@ deriveEq mn ds tyConNm = do
265266
$ decomposeRec rec
266267
toEqTest l r _ = preludeEq l r
267268

269+
deriveOrd ::
270+
forall m. (Functor m, MonadError MultipleErrors m, MonadSupply m)
271+
=> ModuleName
272+
-> [Declaration]
273+
-> ProperName 'TypeName
274+
-> m [Declaration]
275+
deriveOrd mn ds tyConNm = do
276+
tyCon <- findTypeDecl tyConNm ds
277+
compareFun <- mkCompareFunction tyCon
278+
return [ ValueDeclaration (Ident C.compare) Public [] (Right compareFun) ]
279+
where
280+
mkCompareFunction :: Declaration -> m Expr
281+
mkCompareFunction (DataDeclaration _ _ _ args) = lamCase2 "$x" "$y" <$> (concat <$> mapM mkCtorClauses args)
282+
mkCompareFunction (PositionedDeclaration _ _ d) = mkCompareFunction d
283+
mkCompareFunction _ = internalError "mkCompareFunction: expected DataDeclaration"
284+
285+
preludeCtor :: String -> Expr
286+
preludeCtor = Constructor . Qualified (Just (ModuleName [ProperName C.prelude])) . ProperName
287+
288+
preludeAppend :: Expr -> Expr -> Expr
289+
preludeAppend = App . App (Var (Qualified (Just (ModuleName [ProperName C.prelude])) (Ident C.append)))
290+
291+
preludeCompare :: Expr -> Expr -> Expr
292+
preludeCompare = App . App (Var (Qualified (Just (ModuleName [ProperName C.prelude])) (Ident C.compare)))
293+
294+
mkCtorClauses :: (ProperName 'ConstructorName, [Type]) -> m [CaseAlternative]
295+
mkCtorClauses (ctorName, tys) = do
296+
[identsL, identsR] <- replicateM 2 (replicateM (length tys) freshIdent')
297+
let tests = zipWith3 toOrdering (map (Var . Qualified Nothing) identsL) (map (Var . Qualified Nothing) identsR) tys
298+
return [ CaseAlternative [ caseBinder identsL
299+
, caseBinder identsR
300+
]
301+
(Right (appendAll tests))
302+
, CaseAlternative [ ConstructorBinder (Qualified (Just mn) ctorName) (replicate (length tys) NullBinder)
303+
, NullBinder
304+
]
305+
(Right (preludeCtor "LT"))
306+
, CaseAlternative [ NullBinder
307+
, ConstructorBinder (Qualified (Just mn) ctorName) (replicate (length tys) NullBinder)
308+
]
309+
(Right (preludeCtor "GT"))
310+
]
311+
where
312+
caseBinder idents = ConstructorBinder (Qualified (Just mn) ctorName) (map VarBinder idents)
313+
314+
appendAll :: [Expr] -> Expr
315+
appendAll [] = preludeCtor "EQ"
316+
appendAll xs = foldl1 preludeAppend xs
317+
318+
toOrdering :: Expr -> Expr -> Type -> Expr
319+
toOrdering l r ty | Just rec <- objectType ty =
320+
appendAll
321+
. map (\(str, typ) -> toOrdering (Accessor str l) (Accessor str r) typ)
322+
$ decomposeRec rec
323+
toOrdering l r _ = preludeCompare l r
324+
268325
findTypeDecl
269326
:: (Functor m, MonadError MultipleErrors m)
270327
=> ProperName 'TypeName

0 commit comments

Comments
 (0)