mirror of
https://github.com/idris-lang/Idris2.git
synced 2024-12-20 01:41:44 +03:00
48 lines
1.1 KiB
Idris
48 lines
1.1 KiB
Idris
module Data.Linear.LNat
|
|
|
|
import Data.Linear.Bifunctor
|
|
import Data.Linear.Notation
|
|
import Data.Linear.Interface
|
|
|
|
%default total
|
|
|
|
||| Linear Nat
|
|
public export
|
|
data LNat : Type where
|
|
Zero : LNat
|
|
Succ : LNat -@ LNat
|
|
|
|
||| Convert a linear nat to an unrestricted Nat, only usable at the type level
|
|
||| because we canot call `S` with an argument that is expected to be used exactly once
|
|
public export
|
|
0 toNat : LNat -@ Nat
|
|
toNat Zero = Z
|
|
toNat (Succ n) = S (toNat n)
|
|
|
|
export
|
|
Consumable LNat where
|
|
consume Zero = ()
|
|
consume (Succ n) = consume n
|
|
|
|
export
|
|
Duplicable LNat where
|
|
duplicate Zero = [Zero, Zero]
|
|
duplicate (Succ n) = Succ <$> duplicate n
|
|
|
|
||| Add two linear numbers
|
|
export
|
|
add : LNat -@ LNat -@ LNat
|
|
add Zero x = x
|
|
add (Succ v) x = Succ (add v x)
|
|
|
|
||| Multiply two linear numbers
|
|
export
|
|
mult : (1 n : LNat) -> (0 l : LNat) -> {auto 1 ls : toNat n `Copies` l} -> LNat
|
|
mult Zero x {ls = []} = Zero
|
|
mult (Succ v) x {ls = x :: ls} = add x (mult {ls} v x)
|
|
|
|
||| Square a linear number
|
|
export
|
|
square : (1 v : LNat) -> {auto 1 vs : toNat v `Copies` v} -> LNat
|
|
square v {vs} = mult {ls = vs} v v
|