6

Roughly, I have

check : UExpr -> Maybe Expr

And I have a test term

testTerm : UExpr

Which I hope will check successfully, after which I want to extract the resulting Expr and manipulate it further. Basically

realTerm : Expr
just realTerm = check testTerm

Such that this definition would fail to typecheck if check testTerm turned out to be nothing. Is this possible?

luqui
  • 59,485
  • 12
  • 145
  • 204
  • 1
    You might find [Eliminating a Maybe at the type level](http://stackoverflow.com/questions/31105947/eliminating-a-maybe-at-the-type-level) useful. – effectfully Sep 14 '16 at 07:52
  • In contrast to the technical answers below, I want to point out you're are thinking non-functionally. It's like someone who wants to get rid of the `IO` monad and writes imperative code everywhere in Haskell: generally, there is no way to extract the underlying type from a term of type `Maybe` whatever; It's the gist of strong functional programming languages such as Agda, so you must pass the monad all the way around until you find a good way to encode it into value of another type. – 盛安安 Sep 14 '16 at 18:04

2 Answers2

11

The usual deal is to write something like

Just : {X : Set} -> Maybe X -> Set
Just (just x) = One -- or whatever you call the fieldless record type
Just nothing = Zero

justify : {X : Set}(m : Maybe X){p : Just m} -> X
justify (just x) = x
justify nothing {()}

If m computes to a success, the type of p is One and the value is inferred.

luqui
  • 59,485
  • 12
  • 145
  • 204
pigworker
  • 43,025
  • 18
  • 121
  • 214
  • I had just started seeing that idiom around with `True` but didn't really dig in. Thanks. – luqui Sep 14 '16 at 07:20
2

Well I found one way to do it, which is sortof bizarre and magical.

testTerm-checks : Σ Expr (\e -> check testTerm ≡ just e)
testTerm-checks = _ , refl

realTerm : Expr
realTerm = proj₁ testTerm-checks

This gives me the heebie jeebies, but not necessarily in a bad way. Still interested in other ways to do it.

luqui
  • 59,485
  • 12
  • 145
  • 204