我正在用Idris编写一个基本的单子解析器,以熟悉其语法和与Haskell的差异。我已经成功掌握了解析器的基础知识,但我在尝试为解析器创建VerifiedSemigroup和VerifiedMonoid实例时遇到了困难。
以下是解析器类型、Semigroup和Monoid实例,以及VerifiedSemigroup实例的初始内容。
data ParserM a = Parser (String -> List (a, String))
parse : ParserM a -> String -> List (a, String)
parse (Parser p) = p
instance Semigroup (ParserM a) where
p <+> q = Parser (\s => parse p s ++ parse q s)
instance Monoid (ParserM a) where
neutral = Parser (const [])
instance VerifiedSemigroup (ParserM a) where
semigroupOpIsAssociative (Parser p) (Parser q) (Parser r) = ?whatGoesHere
我基本上在intros
之后卡住了,拥有以下证明状态:
-Parser.whatGoesHere> intros
---------- Other goals: ----------
{hole3},{hole2},{hole1},{hole0}
---------- Assumptions: ----------
a : Type
p : String -> List (a, String)
q : String -> List (a, String)
r : String -> List (a, String)
---------- Goal: ----------
{hole4} : Parser (\s => p s ++ q s ++ r s) =
Parser (\s => (p s ++ q s) ++ r s)
-Parser.whatGoesHere>
看起来我应该可以在某种程度上使用rewrite
和appendAssociative
,但我不知道如何"进入"lambda\s
。
无论如何,我被困在练习的定理证明部分 - 我似乎找不到很多关于Idris-centric的定理证明文档。我想也许我需要开始看Agda教程(尽管我坚信我想学的是依赖类型语言Idris!)。
funext:(f,g:a-> b)->((x:a)-> f x = g x )-> f = g
)。可悲的是,据我所知,Agda和Idris都无法证明这个陈述,因此必须将其作为公设。另一种选择是引入自己的相等概念(例如,p = q <=> forall s. parse p s = parse q s'),但我认为Idris 的
VerifiedSemigroup` 不具备处理自定义相等性的功能。 - Vitusfunext = believe me
看起来像是作弊 - 但再说一遍,这并不像我在其他语言中尝试过的玩具问题那样需要严格的证明,如果有的话,只会在注释中。 - h.forrest.alexander