Why doesn't this use of Elem typecheck? - idris

I am quite confused.
module Experiment
import Data.Vect
p1: Elem 5 [3,4,5,6]
p1 = There (There Here)
v : Vect 4 Int
v = 3 :: 4 :: 5 :: 6 :: Nil
p2: Elem 5 v
p2 = There (There Here)
The definition of p2 does not typecheck, while the definition of p1 does. I am using Idris 0.10.2. Is there something I am missing?

Lowercase names in type declarations are interpreted as implicit arguments (like a in length : List a -> Nat which is actually length : {a : Type} -> List a -> Nat). To refer to the defined Vect you can either use an uppercase name or refer by the namespace:
module Experiment
import Data.Vect
A : Vect 4 Int
A = 3 :: 4 :: 5 :: 6 :: Nil
p2: Elem 5 A
p2 = There (There Here)
a : Vect 4 Int
a = 3 :: 4 :: 5 :: 6 :: Nil
p3: Elem 5 Experiment.a
p3 = There (There Here)

Related

Equality proofs and pattern matching in total functions

I know this is a bit contrived example, but I was wondering how do I make the following function total:
total foo : (x : Int) -> {auto prf : x = 10} -> Int
foo 10 = 10
At the moment type checker complains:
Main.foo is not total as there are missing cases
Edit:
Adding impossible branch to HTNWs answer I got it to typecheck this way:
total foo : (x : Int) -> {auto prf : x = 10} -> Int
foo 10 {prf = Refl} = 10
foo x {prf = Refl} impossible
You have to pattern match on the equality, too
total foo : (x : Int) -> {auto prf : x = 10} -> Int
foo 10 {prf=Refl} = 10

Inf value is automatically forced after pattern matching

Let's say we have an infinite list:
data InfList : Type -> Type where
(::) : (value : elem) -> Inf (InfList elem) -> InfList elem
And we want to have finite number of its elements:
getPrefix : (count : Nat) -> InfList a -> List a
getPrefix Z _ = []
getPrefix (S k) (value :: xs) = value :: getPrefix k (?rest)
So, what is left:
a : Type
k : Nat
value : a
xs : InfList a
--------------------------------------
rest : InfList a
It turned out that after pattern matching xs become InfList a instead of Inf (InfList a).
Is there a way to have xs delayed?
It seems to be delayed anyway.
If you execute :x getPrefix 10 one with
one : InfList Int
one = 1 :: one
you get 1 :: getPrefix 9 (1 :: Delay one)
I can't find it anymore in the documentation but idris seems to insert Delay automatically.
Just try to add Delay constructor manually. It's removed implicitly.
getPrefix : (count : Nat) -> InfList a -> List a
getPrefix Z _ = []
getPrefix (S k) (value :: Delay xs) = value :: getPrefix k xs

Helper Function to Determine if Nat `mod` 5 == 0

Xash provided me with a helpful answer on Function to Determine if Nat is Divisible by 5 at Compile-Time (that I re-named from my original long name):
onlyModBy5 : (n : Nat) -> n `modNat` 5 = 0 -> Nat
onlyModBy5 n prf = n
A previous answer educated me how to run it on the REPL using the Refl argument:
-- 5 % 5 == 0, so it should compile
*Test> onlyModBy5 5 Refl
5 : Nat
-- 7 % 5 == 2, so it should not compile
*Test> onlyModBy5 7 Refl
(input):1:12:When checking an application of function Main.onlyModBy5:
Type mismatch between
x = x (Type of Refl)
and
modNat 7 5 = 0 (Expected type)
Specifically:
Type mismatch between
2
and
0
Then, I tried to define a helper function that would provide the second prf (proof) argument for conciseness. In other words, I'd prefer the caller of this function to not have to provide the Refl argument.
onlyModBy5Short : (n : Nat) -> Nat
onlyModBy5Short n = onlyModBy5 n Refl
But, it does not compile:
When checking right hand side of onlyModBy5Short with expected type
Nat
When checking an application of function Main.onlyModBy5:
Type mismatch between
0 = 0 (Type of Refl)
and
modNat n 5 = 0 (Expected type)
Specifically:
Type mismatch between
0
and
Prelude.Nat.modNatNZ, mod' n 4 SIsNotZ n n 4
Holes: Main.onlyModBy5Short
How, if possible, can this function be written?
You can make onlyModBy5's second argument an auto argument:
onlyModBy5 : (n : Nat) -> {auto prf : n `modNat` 5 = 0} -> Nat
onlyModBy5 n = n
This works because for a given literal value of n, n `modNat` 5 can always be reduced, and so n `modNat` 5 = 0 will always reduce to 0 = 0 (in which case the constructor Refl has the right type) unless n is truly not divisible by 5.
Indeed, this will allow you to typecheck
foo : Nat
foo = onlyModBy5 25
but reject
bar : Nat
bar = onlyModBy5 4

How does "There" work in the idris tutorial, page 11, section 3.4.4?

Here is the example from the tutorial, slightly modified for simplicity:
data Vect : Nat -> (b:Type) -> Type where
Nil : Vect Z a
(::) : a -> Vect k a -> Vect (S k) a
data Elem : a -> Vect n a -> Type where
Here : {x:a} -> {xs:Vect n a} -> Elem x (x :: xs)
There : {x,y:a} -> {xs:Vect n a} -> Elem x xs -> Elem x (y :: xs)
testVec : Vect 4 Int
testVec = 3 :: 4 :: 5 :: 6 :: Nil
inVect : Elem 4 testVec
inVect = There Here
I can't understand how There verifies that the value is correct.
As far as I understand it, There works like a function, so it takes the
element of type Here, which when filling in the holes, corresponds to Elem 3 testVec, then sets the first value of testVec to y, and the rest to xs. But since, y isn't used anywhere, I would except this not to cause any restriction.
However, when I try
inVectBroken : Elem 2 testVec
inVectBroken = There Here
I get an error:
When checking an application of constructor There:
Type mismatch between
Elem x (x :: xs) (Type of Here)
and
Elem 2 [4, 5, 6] (Expected type)
Specifically:
Type mismatch between
2
and
4
Can someone explain to me how the above code works (magically?) to restrict There to the tail of Vect?
Here 4 (x :: xs) is a proof that 4 is at the head of (x :: xs), so x = 4. There takes a proof Elem 4 xs that 4 is somewhere in xs and so proofs Elem 4 (y :: xs), that 4 is still somewhere down a extended list. That is where the y goes to. It does not matter what y actually is, it just allows to extend the proof to larger lists. For example:
in1 : Elem 4 (4 :: Nil)
in1 = Here
in2 : Elem 4 (3 :: 4 :: Nil)
in2 = There in1
in3 : Elem 4 (8 :: 4 :: Nil)
in3 = There in1
By the types you see that not the element 4 changes throughout the proof but the list.

Idris Nat literals in types

I'd like Idris to prove that testMult : mult 3 3 = 9 is inhabited.
Unfortunately this is typed as
mult (fromInteger 3) (fromInteger 3) = fromInteger 9 : Type
I can work around it like this:
n3 : Nat; n3 = 3
n9 : Nat; n9 = 9
testMult : mult n3 n3 = n9
testMult = Refl
Is there a way to do something that would be similar to mult (3 : Nat) (3 : Nat) = (9 : Nat)?
You can use the function the : (a : Type) -> a -> a to specify the type when the type inference is failing for you.
testMult : the Nat (3 * 3) = the Nat 9
testMult = Refl
Note that you need to have the at both sides of the equality because Idris has heterogenous equality, that is, (=) : {a : Type} -> {b : Type} -> a -> b -> Type.
Alternatively, you could write
testMult : the Nat 3 * the Nat 3 = the Nat 9
testMult = Refl
If you prefer that style.