I have an Idris module that defines a certain type/predicate IsSet
and a decidability function isSet
over it. It also defines some helper functions to compute that decidability function at type-checking to obtain a proof of IsSet
.
Expressions that use that auxiliary function typecheck correctly inside the module, but don't when I define them in another file and I import the original module:
Test1.idr
module Test1
import Data.List
%default total
%access export
data IsSet : List t -> Type where
IsSetNil : IsSet []
IsSetCons : Not (Elem x xs) -> IsSet xs -> IsSet (x :: xs)
ifNotSetHereThenNeitherThere : Not (IsSet xs) -> Not (IsSet (x :: xs))
ifNotSetHereThenNeitherThere notXsIsSet (IsSetCons xIsInXs xsIsSet) = notXsIsSet xsIsSet
ifIsElemThenConsIsNotSet : Elem x xs -> Not (IsSet (x :: xs))
ifIsElemThenConsIsNotSet xIsInXs (IsSetCons notXIsInXs xsIsSet) = notXIsInXs xIsInXs
isSet : DecEq t => (xs : List t) -> Dec (IsSet xs)
isSet [] = Yes IsSetNil
isSet (x :: xs) with (isSet xs)
isSet (x :: xs) | No notXsIsSet = No $ ifNotSetHereThenNeitherThere notXsIsSet
isSet (x :: xs) | Yes xsIsSet with (isElem x xs)
isSet (x :: xs) | Yes xsIsSet | No notXInXs = Yes $ IsSetCons notXInXs xsIsSet
isSet (x :: xs) | Yes xsIsSet | Yes xInXs = No $ ifIsElemThenConsIsNotSet xInXs
getYes : (d : Dec p) -> case d of { No _ => (); Yes _ => p}
getYes (No _ ) = ()
getYes (Yes prf) = prf
getNo : (d : Dec p) -> case d of { No _ => Not p; Yes _ => ()}
getNo (No cnt) = cnt
getNo (Yes _ ) = ()
setTest1 : IsSet ["x"]
setTest1 = getYes $ isSet ["x"]
Test2.idr
module Test2
import Test1
%default total
%access export
setTest2 : IsSet ["x"]
setTest2 = getYes $ isSet ["x"]
setTest1
typechecks correctly but setTest2
throws the following error:
When checking right hand side of setTest2 with expected type
IsSet ["x"]
Type mismatch between
case block in getYes at Test1.idr:26:30 (IsSet ["x"])
(isSet ["x"])
(isSet ["x"]) (Type of getYes (isSet ["x"]))
and
IsSet ["x"] (Expected type)
I'm using Idris 0.12