如何告诉Agda,财产始终存在于“ if”的分支?
说我想拥有一个digit
类型,该类型是char
仅数字的细化:
open import Data.Bool using (Bool; true; if_then_else_)
open import Data.Char using (Char; isDigit)
open import Data.Maybe using (Maybe; just; nothing)
data IsTrue : Bool → Set where
is-true : IsTrue true
data IsDigit (c : Char) : Set where
is-digit : {p : IsTrue (isDigit c)} → IsDigit c
data Digit : Set where
digit : (c : Char) → {p : IsDigit c} → Digit
然后,我可以构造digit
for <代码>'0'喜欢这样(尽管我似乎需要通过的明显参数令人沮丧):
0-digit : Digit
0-digit = digit '0' {is-digit {_} {is-true}}
但是,如果我想要一个任意char> char
并返回也许Digit ,我似乎无法与
然后在
分支中交流Agda,iSdigit c
始终保持。如何使Agda可见?
在某些语言中,这将是一种流量打字的形式,但是如果我正确理解,AGDA在构造函数上进行模式匹配时只有“流键入”。如果我在'0','1',...'9'
上完全匹配,它 do 编译,但这很乏味,似乎很不幸。
maybeFromChar : Char → Maybe Digit
maybeFromChar c =
if isDigit c
then just (digit c {is-digit {c} {is-true}})
else nothing
.../Foo.agda:20,39-46
true != isDigit c of type Bool
when checking that the expression is-true has type
IsTrue (isDigit c)
(也欢迎改善我的建模方式数字>的建议。)
Say I want to have a Digit
type that is a refinement of Char
to only digits:
open import Data.Bool using (Bool; true; if_then_else_)
open import Data.Char using (Char; isDigit)
open import Data.Maybe using (Maybe; just; nothing)
data IsTrue : Bool → Set where
is-true : IsTrue true
data IsDigit (c : Char) : Set where
is-digit : {p : IsTrue (isDigit c)} → IsDigit c
data Digit : Set where
digit : (c : Char) → {p : IsDigit c} → Digit
I can then construct, e.g., the Digit
for '0'
like so (although the obvious parameters that I seem to need to pass are frustrating):
0-digit : Digit
0-digit = digit '0' {is-digit {_} {is-true}}
However, if I want a function that takes an arbitrary Char
and returns Maybe Digit
, I can't seem to communicate to Agda that in the then
branch, isDigit c
always holds. How do I make this visible to Agda?
In some languages, this would be a form of flow typing, but if I understand correctly, Agda only has "flow typing" when pattern-matching on constructors. It does compile if I exhaustively match on '0', '1', ... '9'
, but that's tedious and seems unfortunate.
maybeFromChar : Char → Maybe Digit
maybeFromChar c =
if isDigit c
then just (digit c {is-digit {c} {is-true}})
else nothing
.../Foo.agda:20,39-46
true != isDigit c of type Bool
when checking that the expression is-true has type
IsTrue (isDigit c)
(Suggestions for improvements to the way I'm modeling Digit
are welcome as well.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用记住匹配项(您需要将
false
添加到data.bool
的导入列表中:您还可以使用
if_then_else _ aka
bool
的消除器:You can use the
inspect
idiom to remember the match (you'll need to addfalse
to the import list ofData.Bool
):You can also use the dependent version of
if_then_else_
a.k.a. the eliminator ofBool
: