Idris2/libs/prelude/Prelude/Basics.idr
André Videla 75032a7164
Emit warning for fixities with no export modifiers (#3234)
* Emit warning for fixities with no export modifiers

This is to help update all the existing code to program with explicit
fixity export directives in preparation for the behavioral change where
they will become private by default.
2024-04-03 15:41:57 +01:00

206 lines
4.7 KiB
Idris

module Prelude.Basics
import Builtin
import Prelude.Ops
%default total
||| `Not x` is an alias for `x -> Void`, indicating that any term of type `x`
||| leads to a contradiction. It can be used in conjunction with `void` or
||| `absurd`.
public export
Not : Type -> Type
Not x = x -> Void
-----------------------
-- UTILITY FUNCTIONS --
-----------------------
||| Manually assign a type to an expression.
||| @ a the type to assign
||| @ x the element to get the type
public export %inline
the : (0 a : Type) -> (1 x : a) -> a
the _ x = x
||| Identity function.
public export %inline
id : (x : a) -> a
id x = x
||| Function that duplicates its input
public export
dup : a -> (a, a)
dup x = (x, x)
||| Constant function. Ignores its second argument.
public export %inline
const : a -> b -> a
const x = \value => x
||| Function composition.
public export %inline %tcinline
(.) : (b -> c) -> (a -> b) -> a -> c
(.) f g = \x => f (g x)
||| Composition of a two-argument function with a single-argument one.
||| `(.:)` is like `(.)` but the second argument and the result are two-argument functions.
||| This operator is also known as "blackbird operator".
public export %inline %tcinline
(.:) : (c -> d) -> (a -> b -> c) -> a -> b -> d
(.:) = (.) . (.)
||| `on b u x y` runs the binary function b on the results of applying
||| unary function u to two arguments x and y. From the opposite perspective,
||| it transforms two inputs and combines the outputs.
|||
||| ```idris example
||| ((+) `on` f) x y = f x + f y
||| ```
|||
||| Typical usage:
|||
||| ```idris example
||| sortBy (compare `on` fst).
||| ```
public export %tcinline
on : (b -> b -> c) -> (a -> b) -> a -> a -> c
on f g = \x, y => g x `f` g y
export infixl 0 `on`
||| Takes in the first two arguments in reverse order.
||| @ f the function to flip
public export %tcinline
flip : (f : a -> b -> c) -> b -> a -> c
flip f = \x, y => f y x
||| Function application.
public export %tcinline
apply : (a -> b) -> a -> b
apply f = \a => f a
public export
curry : ((a, b) -> c) -> a -> b -> c
curry f a b = f (a, b)
public export
uncurry : (a -> b -> c) -> (a, b) -> c
uncurry f (a, b) = f a b
||| ($) is compiled specially to shortcut any tricky unification issues, but if
||| it did have a type this is what it would be, and it might be useful to
||| use directly sometimes (e.g. in higher order functions)
public export
($) : forall a, b . ((x : a) -> b x) -> (x : a) -> b x
($) f a = f a
-------------------
-- PROOF HELPERS --
-------------------
||| Equality is a congruence.
public export
cong : (0 f : t -> u) -> (0 p : a = b) -> f a = f b
cong f Refl = Refl
||| Two-holed congruence.
export
-- These are natural in equational reasoning.
cong2 : (0 f : t1 -> t2 -> u) -> (0 p1 : a = b) -> (0 p2 : c = d) -> f a c = f b d
cong2 f Refl Refl = Refl
||| Dependent version of `cong`.
public export
depCong : {0 p : a -> Type} ->
(0 f : (x : a) -> p x) ->
{0 x1, x2 : a} ->
(prf : x1 = x2) ->
f x1 = f x2
depCong f Refl = Refl
||| Dependent version of `cong2`.
public export
depCong2 : {0 p : a -> Type} ->
{0 q : (x : a) -> (y : p x) -> Type} ->
(0 f : (x : a) -> (y : p x) -> q x y) ->
{0 x1, x2 : a} -> (prfX : x1 = x2) ->
{0 y1 : p x1} -> {y2 : p x2} ->
(prfY : y1 = y2) -> f x1 y1 = f x2 y2
depCong2 f Refl Refl = Refl
||| Irrelevant equalities can always be made relevant
export
irrelevantEq : (0 _ : a ~=~ b) -> a ~=~ b
irrelevantEq Refl = Refl
--------------
-- BOOLEANS --
--------------
||| Boolean Data Type.
public export
data Bool = False | True
||| Boolean NOT.
%inline
public export
not : (b : Bool) -> Bool
not True = False
not False = True
||| Boolean AND only evaluates the second argument if the first is `True`.
%inline
public export
(&&) : (b : Bool) -> Lazy Bool -> Bool
(&&) True x = x
(&&) False x = False
||| Boolean OR only evaluates the second argument if the first is `False`.
%inline
public export
(||) : (b : Bool) -> Lazy Bool -> Bool
(||) True x = True
(||) False x = x
||| Non-dependent if-then-else
%inline
public export
ifThenElse : (b : Bool) -> Lazy a -> Lazy a -> a
ifThenElse True l r = l
ifThenElse False l r = r
%inline
public export
intToBool : Int -> Bool
intToBool 0 = False
intToBool x = True
--------------
-- LISTS --
--------------
||| Generic lists.
public export
data List a =
||| Empty list
Nil
| ||| A non-empty list, consisting of a head element and the rest of the list.
(::) a (List a)
%name List xs, ys, zs
||| Snoc lists.
public export
data SnocList a =
||| Empty snoc-list
Lin
| ||| A non-empty snoc-list, consisting of the rest of the snoc-list and the final element.
(:<) (SnocList a) a
%name SnocList sx, sy, sz