如何在Agda中使用类型实例?

时间:2017-11-08 05:16:10

标签: agda

我知道如何定义类型类,在阅读RawMonadRawMonadZeroRawApplicative等定义后,我实现了一些简单的类型实例:

data Parser (A : Set) : Set where
  MkParser : (String → List (A × String)) → Parser A

ParserMonad : RawMonad Parser
ParserMonad = record {
    return = λ a → MkParser λ s → < a , s > ∷ []
  ; _>>=_  = λ p f → MkParser $ concatMap (tuple $ parse ∘ f) ∘ parse p
  }

但是当我尝试在ParserMonad.return的实施中使用ParserApplicative时,我失败了:

ParserApplicative : RawApplicative Parser
ParserApplicative = record {
    pure = ParserMonad.return -- compile error
  ; _⊛_  = ...
  }

我的问题是:如何使用ParserMonad.return来实施ParserApplicative.pure?我该怎么做?或者我应该读什么文件?

1 个答案:

答案 0 :(得分:1)

这里你没有使用实例参数,你正在使用记录。 Instance arguments是一个独立的机制,结合记录,可以用来模拟类型类之类的东西。

回到记录,要使用f类型的记录r的字段R,您可以执行各种操作:

  • 使用应用于R.f的投影r
 a = R.f r
  • 将与M内容对应的模块r命名为R,并在其中使用定义f
module M = R r
a = M.f
  • 打开该模块并直接使用f
open module R r
a = f

使用第一种选择,在你的情况下,它会给我们:

ParserApplicative : RawApplicative Parser
ParserApplicative = record {
   pure = RawMonad.return ParserMonad
   (...)
   }