mirror of
https://github.com/idris-lang/Idris2.git
synced 2024-12-24 20:23:11 +03:00
75032a7164
* 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.
281 lines
7.4 KiB
Idris
281 lines
7.4 KiB
Idris
module Builtin
|
|
|
|
%default total
|
|
|
|
-- The most primitive data types; things which are used by desugaring
|
|
|
|
-- Totality assertions
|
|
|
|
||| Assert to the totality checker that the given expression will always
|
|
||| terminate.
|
|
|||
|
|
||| The multiplicity of its argument is 1, so `assert_total` won't affect how
|
|
||| many times variables are used. If you're not writing a linear function,
|
|
||| this doesn't make a difference.
|
|
|||
|
|
||| Note: assert_total can reduce at compile time, if required for unification,
|
|
||| which might mean that it's no longer guarded a subexpression. Therefore,
|
|
||| it is best to use it around the smallest possible subexpression.
|
|
%inline %unsafe
|
|
public export
|
|
assert_total : (1 _ : a) -> a
|
|
assert_total x = x
|
|
|
|
||| Assert to the totality checker that y is always structurally smaller than x
|
|
||| (which is typically a pattern argument, and *must* be in normal form for
|
|
||| this to work).
|
|
|||
|
|
||| The multiplicity of x is 0, so in a linear function, you can pass values to
|
|
||| x even if they have already been used.
|
|
||| The multiplicity of y is 1, so `assert_smaller` won't affect how many times
|
|
||| its y argument is used.
|
|
||| If you're not writing a linear function, the multiplicities don't make a
|
|
||| difference.
|
|
|||
|
|
||| @ x the larger value (typically a pattern argument)
|
|
||| @ y the smaller value (typically an argument to a recursive call)
|
|
%inline %unsafe
|
|
public export
|
|
assert_smaller : (0 x : a) -> (1 y : b) -> b
|
|
assert_smaller x y = y
|
|
|
|
-- Unit type and pairs
|
|
|
|
||| The canonical single-element type, also known as the trivially true
|
|
||| proposition.
|
|
public export
|
|
data Unit =
|
|
||| The trivial constructor for `()`.
|
|
MkUnit
|
|
|
|
||| The non-dependent pair type, also known as conjunction.
|
|
public export
|
|
data Pair : Type -> Type -> Type where
|
|
||| A pair of elements.
|
|
||| @ a the left element of the pair
|
|
||| @ b the right element of the pair
|
|
MkPair : {0 a, b : Type} -> (x : a) -> (y : b) -> Pair a b
|
|
|
|
||| Return the first element of a pair.
|
|
public export
|
|
fst : {0 a, b : Type} -> (a, b) -> a
|
|
fst (x, y) = x
|
|
|
|
||| Return the second element of a pair.
|
|
public export
|
|
snd : {0 a, b : Type} -> (a, b) -> b
|
|
snd (x, y) = y
|
|
|
|
||| Swap the elements in a pair
|
|
public export
|
|
swap : (a, b) -> (b, a)
|
|
swap (x, y) = (y, x)
|
|
|
|
-- This directive tells auto implicit search what to use to look inside pairs
|
|
%pair Pair fst snd
|
|
|
|
export infixr 5 #
|
|
|
|
||| A pair type where each component is linear
|
|
public export
|
|
data LPair : Type -> Type -> Type where
|
|
||| A linear pair of elements.
|
|
||| If you take one copy of the linear pair apart
|
|
||| then you only get one copy of its left and right elements.
|
|
||| @ a the left element of the pair
|
|
||| @ b the right element of the pair
|
|
(#) : (1 _ : a) -> (1 _ : b) -> LPair a b
|
|
|
|
namespace DPair
|
|
||| Dependent pairs aid in the construction of dependent types by providing
|
|
||| evidence that some value resides in the type.
|
|
|||
|
|
||| Formally, speaking, dependent pairs represent existential quantification -
|
|
||| they consist of a witness for the existential claim and a proof that the
|
|
||| property holds for it.
|
|
|||
|
|
||| @ a the value to place in the type.
|
|
||| @ p the dependent type that requires the value.
|
|
public export
|
|
record DPair a (p : a -> Type) where
|
|
constructor MkDPair
|
|
fst : a
|
|
snd : p fst
|
|
|
|
||| A dependent variant of LPair, pairing a result value with a resource
|
|
||| that depends on the result value
|
|
public export
|
|
data Res : (a : Type) -> (a -> Type) -> Type where
|
|
(#) : (val : a) -> (1 r : t val) -> Res a t
|
|
|
|
-- The empty type
|
|
|
|
||| The empty type, also known as the trivially false proposition.
|
|
|||
|
|
||| Use `void` or `absurd` to prove anything if you have a variable of type
|
|
||| `Void` in scope.
|
|
public export
|
|
data Void : Type where
|
|
|
|
-- Equality
|
|
|
|
public export
|
|
data Equal : forall a, b . a -> b -> Type where
|
|
[search a b]
|
|
Refl : {0 x : a} -> Equal x x
|
|
|
|
%name Equal prf
|
|
|
|
export infix 6 ===, ~=~
|
|
|
|
-- An equality type for when you want to assert that each side of the
|
|
-- equality has the same type, but there's not other evidence available
|
|
-- to help with unification
|
|
public export
|
|
(===) : (x : a) -> (y : a) -> Type
|
|
(===) = Equal
|
|
|
|
||| Explicit heterogeneous ("John Major") equality. Use this when Idris
|
|
||| incorrectly chooses homogeneous equality for `(=)`.
|
|
||| @ a the type of the left side
|
|
||| @ b the type of the right side
|
|
||| @ x the left side
|
|
||| @ y the right side
|
|
public export
|
|
(~=~) : (x : a) -> (y : b) -> Type
|
|
(~=~) = Equal
|
|
|
|
||| Perform substitution in a term according to some equality.
|
|
|||
|
|
||| Like `replace`, but with an explicit predicate, and applying the rewrite in
|
|
||| the other direction, which puts it in a form usable by the `rewrite` tactic
|
|
||| and term.
|
|
%inline
|
|
public export
|
|
rewrite__impl : {0 x, y : a} -> (0 p : _) ->
|
|
(0 rule : x = y) -> (1 val : p y) -> p x
|
|
rewrite__impl p Refl prf = prf
|
|
|
|
%rewrite Equal rewrite__impl
|
|
|
|
||| Perform substitution in a term according to some equality.
|
|
%inline
|
|
public export
|
|
replace : forall x, y, p . (0 rule : x = y) -> (1 _ : p x) -> p y
|
|
replace Refl prf = prf
|
|
|
|
||| Symmetry of propositional equality.
|
|
%inline
|
|
public export
|
|
sym : (0 rule : x ~=~ y) -> y ~=~ x
|
|
sym Refl = Refl
|
|
|
|
||| Transitivity of propositional equality.
|
|
%inline
|
|
public export
|
|
trans : forall a, b, c . (0 l : a = b) -> (0 r : b = c) -> a = c
|
|
trans Refl Refl = Refl
|
|
|
|
||| Injectivity of MkDPair (first components)
|
|
export
|
|
mkDPairInjectiveFst : MkDPair a pa === MkDPair b qb -> a === b
|
|
mkDPairInjectiveFst Refl = Refl
|
|
|
|
||| Injectivity of MkDPair (snd components)
|
|
export
|
|
mkDPairInjectiveSnd : MkDPair a pa === MkDPair a qa -> pa === qa
|
|
mkDPairInjectiveSnd Refl = Refl
|
|
|
|
||| Subvert the type checker. This function is abstract, so it will not reduce
|
|
||| in the type checker. Use it with care - it can result in segfaults or
|
|
||| worse!
|
|
public export %inline %unsafe
|
|
believe_me : a -> b -- TODO: make linear
|
|
believe_me v = prim__believe_me _ _ v
|
|
|
|
||| Assert to the usage checker that the given function uses its argument linearly.
|
|
public export %unsafe
|
|
assert_linear : (1 f : a -> b) -> (1 val : a) -> b
|
|
assert_linear = believe_me id
|
|
where
|
|
id : (1 f : a -> b) -> a -> b
|
|
id f = f
|
|
|
|
export partial %unsafe
|
|
idris_crash : String -> a
|
|
idris_crash = prim__crash _
|
|
|
|
public export %inline
|
|
delay : a -> Lazy a
|
|
delay x = Delay x
|
|
|
|
public export %inline
|
|
force : Lazy a -> a
|
|
force x = Force x
|
|
|
|
%stringLit fromString
|
|
|
|
||| Interface for types that can be constructed from string literals.
|
|
public export
|
|
interface FromString ty where
|
|
constructor MkFromString
|
|
||| Conversion from String.
|
|
fromString : String -> ty
|
|
|
|
%allow_overloads fromString
|
|
|
|
%inline
|
|
public export
|
|
FromString String where
|
|
fromString s = s
|
|
|
|
%defaulthint
|
|
%inline
|
|
public export
|
|
defaultString : FromString String
|
|
defaultString = %search
|
|
|
|
%charLit fromChar
|
|
|
|
||| Interface for types that can be constructed from char literals.
|
|
public export
|
|
interface FromChar ty where
|
|
constructor MkFromChar
|
|
||| Conversion from Char.
|
|
fromChar : Char -> ty
|
|
|
|
%allow_overloads fromChar
|
|
|
|
%inline
|
|
public export
|
|
FromChar Char where
|
|
fromChar s = s
|
|
|
|
%defaulthint
|
|
%inline
|
|
public export
|
|
defaultChar : FromChar Char
|
|
defaultChar = %search
|
|
|
|
%doubleLit fromDouble
|
|
|
|
||| Interface for types that can be constructed from double literals.
|
|
public export
|
|
interface FromDouble ty where
|
|
constructor MkFromDouble
|
|
||| Conversion from Double.
|
|
fromDouble : Double -> ty
|
|
|
|
%allow_overloads fromDouble
|
|
|
|
%inline
|
|
public export
|
|
FromDouble Double where
|
|
fromDouble s = s
|
|
|
|
%defaulthint
|
|
%inline
|
|
public export
|
|
defaultDouble : FromDouble Double
|
|
defaultDouble = %search
|