Skip to content

Commit

Permalink
Update pragmas (#122)
Browse files Browse the repository at this point in the history
* Closes #121 
* Depends on anoma/juvix#2944
* Includes #123
* Adds `Stdlib.Data.Range` to the Prelude. Since now `for` and `rfor`
are trait fields, there is no name clash anymore.

---------

Co-authored-by: Paul Cadman <git@paulcadman.dev>
  • Loading branch information
lukaszcz and paulcadman authored Aug 14, 2024
1 parent 5424a48 commit 17a82dd
Show file tree
Hide file tree
Showing 16 changed files with 94 additions and 34 deletions.
2 changes: 2 additions & 0 deletions Stdlib/Data/Bool.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Stdlib.Trait.Eq open;
import Stdlib.Trait.Ord open;
import Stdlib.Trait.Show open;

{-# specialize: true, inline: case #-}
instance
boolEqI : Eq Bool :=
mkEq
Expand All @@ -14,6 +15,7 @@ boolEqI : Eq Bool :=
| _ _ := false
};

{-# specialize: true, inline: case #-}
instance
boolOrdI : Ord Bool :=
mkOrd
Expand Down
2 changes: 1 addition & 1 deletion Stdlib/Data/Bool/Base.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Juvix.Builtin.V1.Bool open public;
import Stdlib.Data.Fixity open;

--- Logical negation.
{-# isabelle-function: {name: "¬"} #-}
{-# isabelle-function: {name: "\\<not>"} #-}
not : Bool → Bool
| true := false
| false := true;
Expand Down
4 changes: 4 additions & 0 deletions Stdlib/Data/List.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,25 @@ showListI {A} {{Show A}} : Show (List A) :=
| s := "(" ++str go s ++str ")"
};

{-# specialize: true, inline: case #-}
instance
functorListI : Functor List :=
mkFunctor@{
map := listMap
};

{-# specialize: true, inline: true #-}
instance
monomorphicFunctorListI {A} : Monomorphic.Functor (List A) A := fromPolymorphicFunctor;

{-# specialize: true, inline: case #-}
instance
polymorphicFoldableListI : Polymorphic.Foldable List :=
Polymorphic.mkFoldable@{
for := listFor;
rfor := listRfor
};

{-# specialize: true, inline: true #-}
instance
foldableListI {A} : Foldable (List A) A := fromPolymorphicFoldable;
4 changes: 4 additions & 0 deletions Stdlib/Data/Maybe.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Stdlib.Trait.Functor open;
import Stdlib.Data.Bool.Base open;
import Stdlib.Data.String.Base open;

{-# specialize: true, inline: case #-}
instance
eqMaybeI {A} {{Eq A}} : Eq (Maybe A) :=
mkEq
Expand All @@ -27,6 +28,7 @@ showMaybeI {A} {{Show A}} : Show (Maybe A) :=
| (just a) := "just " ++str Show.show a
};

{-# specialize: true, inline: case #-}
instance
ordMaybeI {A} {{Ord A}} : Ord (Maybe A) :=
mkOrd
Expand All @@ -37,6 +39,7 @@ ordMaybeI {A} {{Ord A}} : Ord (Maybe A) :=
| (just _) nothing := GT
};

{-# specialize: true, inline: case #-}
instance
functorMaybeI : Functor Maybe :=
mkFunctor@{
Expand All @@ -45,5 +48,6 @@ functorMaybeI : Functor Maybe :=
| (just a) := just (f a)
};

{-# specizalize: true, inline: true #-}
instance
monomorphicFunctorMaybeI {A} : Monomorphic.Functor (Maybe A) A := fromPolymorphicFunctor;
2 changes: 2 additions & 0 deletions Stdlib/Data/Pair.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import Stdlib.Trait.Eq open;
import Stdlib.Trait.Ord open;
import Stdlib.Trait.Show open;

{-# specialize: true, inline: case #-}
instance
eqProductI {A B} : {{Eq A}} -> {{Eq B}} -> Eq (Pair A B)
| {{mkEq eq-a}} {{mkEq eq-b}} := mkEq λ {(a1, b1) (a2, b2) := eq-a a1 a2 && eq-b b1 b2};

{-# specialize: true, inline: case #-}
instance
ordProductI {A B} : {{Ord A}} -> {{Ord B}} -> Ord (Pair A B)
| {{mkOrd cmp-a}} {{mkOrd cmp-b}} :=
Expand Down
78 changes: 53 additions & 25 deletions Stdlib/Data/Range.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -12,53 +12,81 @@ import Stdlib.Data.Nat open;
type Range N :=
mkRange {
low : N;
high : N;
step : N
high : N
};

syntax iterator for {init := 1; range := 1};

{-# specialize: [1, 2, 3, 5] #-}
for {A N} {{Ord N}} {{Natural N}} (f : A → N → A) (a : A) : Range N → A
| mkRange@{low; high; step} :=
let
{-# specialize-by: [f] #-}
terminating
go (acc : A) (n : N) : A := ite (n > high) acc (go (f acc n) (n + step));
in go a low;
type StepRange N :=
mkStepRange {
range : Range N;
step : N
};

syntax operator to range;

--- `x to y` is the range [x..y]
{-# inline: always #-}
to {N} {{Natural N}} (l h : N) : Range N := mkRange l h 1;
to {N} {{Natural N}} (l h : N) : Range N := mkRange l h;

syntax operator step step;

--- `x to y step s` is the range [x, x + s, ..., y]
{-# inline: always #-}
step {N} (r : Range N) (s : N) : Range N := r@Range{step := s};
step {N} (r : Range N) (s : N) : StepRange N := mkStepRange r s;

-- This instance assumes that `low <= high`.
{-# specialize: true, inline: case #-}
instance
foldableRangeI {N} {{Eq N}} {{Natural N}} : Foldable (Range N) N :=
mkFoldable@{
{-# specialize: [1, 3] #-}
for {B : Type} (f : B -> N -> B) (ini : B) : Range N -> B
| (mkRange low high) :=
let
{-# specialize-by: [f, high] #-}
terminating
go (acc : B) (next : N) : B :=
if
| next == high := f acc next
| else := go (f acc next) (next + 1);
in go ini low;
{-# specialize: [1, 3] #-}
rfor {B : Type} (f : B -> N -> B) (ini : B) : Range N -> B
| (mkRange low high) :=
let
{-# specialize-by: [f, high] #-}
terminating
go (next : N) : B :=
if
| next == high := f ini next
| else := f (go (next + 1)) next;
in go low
};

-- This instance assumes that (low + step*k > high) for some k.
{-# specialize: true, inline: case #-}
instance
foldableRangeI {N} {{Ord N}} {{Natural N}} : Foldable (Range N) N :=
foldableStepRangeI {N} {{Ord N}} {{Natural N}} : Foldable (StepRange N) N :=
mkFoldable@{
for {B : Type} (g : B -> N -> B) (ini : B) : Range N -> B
| (mkRange low high step) :=
{-# specialize: [1, 3] #-}
for {B : Type} (f : B -> N -> B) (ini : B) : StepRange N -> B
| (mkStepRange (mkRange low high) step) :=
let
{-# specialize-by: [f, high, step] #-}
terminating
go (acc : B) (next : N) : B :=
if
| next <= high := go (g acc next) (next + step)
| else := acc;
| next > high := acc
| else := go (f acc next) (next + step);
in go ini low;
rfor {B : Type} (g : B -> N -> B) (ini : B) : Range N -> B
| (mkRange low high step) :=
{-# specialize: [1, 3] #-}
rfor {B : Type} (f : B -> N -> B) (ini : B) : StepRange N -> B
| (mkStepRange (mkRange low high) step) :=
let
{-# specialize-by: [f, high, step] #-}
terminating
go (base : B) (next : N) : B :=
go (next : N) : B :=
if
| next <= high := g (go base (next + step)) next
| else := base;
in go ini low
| next <= high := f (go (next + step)) next
| else := ini;
in go low
};
4 changes: 4 additions & 0 deletions Stdlib/Data/Result.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Stdlib.Trait.Eq open;
import Stdlib.Trait.Ord open;
import Stdlib.Trait.Functor open;

{-# specialize: true, inline: case #-}
instance
ordResultI {A B} {{Ord A}} {{Ord B}} : Ord (Result A B) :=
mkOrd@{
Expand All @@ -17,6 +18,7 @@ ordResultI {A B} {{Ord A}} {{Ord B}} : Ord (Result A B) :=
| (ok _) (error _) := GT
};

{-# specialize: true, inline: case #-}
instance
eqResultI {A B} {{Eq A}} {{Eq B}} : Eq (Result A B) :=
mkEq@{
Expand All @@ -26,12 +28,14 @@ eqResultI {A B} {{Eq A}} {{Eq B}} : Eq (Result A B) :=
| _ _ := false
};

{-# specialize: true, inline: case #-}
instance
functorResultI {err} : Functor (Result err) :=
mkFunctor@{
map := mapOk
};

{-# specialize: true, inline: true #-}
instance
monomorphicFunctorResultI {err res} : Monomorphic.Functor (Result err res) res :=
fromPolymorphicFunctor;
3 changes: 3 additions & 0 deletions Stdlib/Data/Unit.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ ordUnitI : Ord Unit := mkOrd λ {unit unit := EQ};
instance
showUnitI : Show Unit := mkShow λ {unit := "unit"};

{-# specialize: true, inline: case #-}
instance
foldableUnitI : Foldable Unit Unit :=
mkFoldable@{
{-# inline: true #-}
rfor {B : Type} (f : B -> Unit -> B) (ini : B) (_ : Unit) : B := f ini unit;
{-# inline: true #-}
for {B : Type} (f : B -> Unit -> B) (ini : B) (_ : Unit) : B := f ini unit
};
1 change: 1 addition & 0 deletions Stdlib/Prelude.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Stdlib.Data.Field open public;
import Stdlib.Data.Pair open public;
import Stdlib.Data.String open public;
import Stdlib.Data.Result open public;
import Stdlib.Data.Range open public;
import Stdlib.Function open public;
import Stdlib.System.IO open public;

Expand Down
2 changes: 1 addition & 1 deletion Stdlib/Trait/Eq.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ syntax operator /= comparison;
== {A} {{Eq A}} : A -> A -> Bool := Eq.eq;

--- Tests for inequality.
{-# inline: always, isabelle-operator: {name: "", prec: 50, assoc: none} #-}
{-# inline: always, isabelle-operator: {name: "\\<noteq>", prec: 50, assoc: none} #-}
/= {A} {{Eq A}} (x y : A) : Bool := not (x == y);
6 changes: 4 additions & 2 deletions Stdlib/Trait/Foldable/Monomorphic.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,30 @@ import Stdlib.Function open;
import Stdlib.Trait.Foldable.Polymorphic as Poly;

--- A trait for combining elements into a single result, processing one element at a time.
{-# specialize: true #-}
trait
type Foldable (container elem : Type) :=
mkFoldable {
syntax iterator for {init := 1; range := 1};
{-# inline: 0 #-}
for : {B : Type} -> (B -> elem -> B) -> B -> container -> B;

syntax iterator rfor {init := 1; range := 1};
{-# inline: 0 #-}
rfor : {B : Type} -> (B -> elem -> B) -> B → container → B
};

open Foldable public;

--- Make a monomorphic ;Foldable; instance from a polymorphic one.
--- All polymorphic types that are an instance of ;Poly.Foldable; should use this function to create their monomorphic ;Foldable; instance.
{-# inline: case #-}
fromPolymorphicFoldable
{f : Type -> Type} {{foldable : Poly.Foldable f}} {elem} : Foldable (f elem) elem :=
mkFoldable@{
for := Poly.for;
rfor := Poly.rfor
};

{-# inline: true #-}
foldl
{container elem}
{{Foldable container elem}}
Expand All @@ -37,6 +38,7 @@ foldl
: B := for (acc := ini) (x in ls) {g acc x};

--- Combine the elements of the type using the provided function starting with the element in the right-most position.
{-# inline: 2 #-}
foldr
{container elem : Type}
{{Foldable container elem}}
Expand Down
4 changes: 2 additions & 2 deletions Stdlib/Trait/Foldable/Polymorphic.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@ trait
type Foldable (f : Type -> Type) :=
mkFoldable {
syntax iterator for {init := 1; range := 1};
{-# inline: 0 #-}
for : {A B : Type} -> (B -> A -> B) -> B -> f A -> B;

syntax iterator rfor {init := 1; range := 1};
{-# inline: 0 #-}
rfor : {A B : Type} -> (B → A → B) -> B → f A → B
};

open Foldable public;

--- Combine the elements of the type using the provided function starting with the element in the left-most position.
{-# inline: true #-}
foldl {f : Type -> Type} {{Foldable f}} {A B : Type} (g : B -> A -> B) (ini : B) (ls : f A) : B :=
for (acc := ini) (x in ls) {g acc x};

--- Combine the elements of the type using the provided function starting with the element in the right-most position.
{-# inline: true #-}
foldr {f : Type -> Type} {{Foldable f}} {A B : Type} (g : A -> B -> B) (ini : B) (ls : f A) : B :=
rfor (acc := ini) (x in ls) {g x acc};
5 changes: 5 additions & 0 deletions Stdlib/Trait/Functor/Monomorphic.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,28 @@ import Stdlib.Data.Fixity open;
import Stdlib.Data.Unit open;
import Stdlib.Trait.Functor.Polymorphic as Poly;

{-# specialize: true #-}
trait
type Functor (container elem : Type) :=
mkFunctor {
syntax iterator map {init := 0; range := 1};
{-# specialize: [1] #-}
map : (elem -> elem) -> container -> container
};

open Functor public;

{-# inline: case #-}
fromPolymorphicFunctor {f : Type -> Type} {{Poly.Functor f}} {elem} : Functor (f elem) elem :=
mkFunctor@{
map := Poly.map
};

syntax operator <$> lapp;
{-# inline: true #-}
<$> {container elem} {{Functor container elem}} : (elem -> elem) -> container -> container := map;

syntax operator $> lapp;
{-# inline: true #-}
$> {container elem : Type} {{Functor container elem}} (fa : container) (b : elem) : container :=
λ {_ := b} <$> fa;
5 changes: 5 additions & 0 deletions Stdlib/Trait/Functor/Polymorphic.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@ module Stdlib.Trait.Functor.Polymorphic;
import Stdlib.Data.Fixity open;
import Stdlib.Data.Unit open;

{-# specialize: true #-}
trait
type Functor (f : Type -> Type) :=
mkFunctor {
syntax iterator map {init := 0; range := 1};
{-# specialize: [1] #-}
map : {A B : Type} -> (A -> B) -> f A -> f B
};

open Functor public;

syntax operator <$> lapp;
{-# inline: true #-}
<$> {f : Type -> Type} {{Functor f}} {A B} : (A -> B) -> f A -> f B := map;

syntax operator $> lapp;
{-# inline: true #-}
$> {f : Type → Type} {A B : Type} {{Functor f}} (fa : f A) (b : B) : f B := λ {_ := b} <$> fa;

{-# inline: true #-}
void {f : Type → Type} {A : Type} {{Functor f}} (fa : f A) : f Unit := fa $> unit;
4 changes: 2 additions & 2 deletions Stdlib/Trait/Ord.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type Ord A := mkOrd {cmp : A -> A -> Ordering};
syntax operator <= comparison;

--- Returns ;true; iff the first element is less than or equal to the second.
{-# inline: always, isabelle-operator: {name: "", prec: 50, assoc: none} #-}
{-# inline: always, isabelle-operator: {name: "\\<le>", prec: 50, assoc: none} #-}
<= {A} {{Ord A}} (x y : A) : Bool :=
case Ord.cmp x y of
| EQ := true
Expand All @@ -63,7 +63,7 @@ syntax operator > comparison;
syntax operator >= comparison;

--- Returns ;true; iff the first element is greater than or equal to the second.
{-# inline: always, isabelle-operator: {name: "", prec: 50, assoc: none} #-}
{-# inline: always, isabelle-operator: {name: "\\<ge>", prec: 50, assoc: none} #-}
>= {A} {{Ord A}} (x y : A) : Bool := y <= x;

--- Returns the smaller element.
Expand Down
Loading

0 comments on commit 17a82dd

Please sign in to comment.