как перевести Haskell на Scalaz?

Один из моих старшеклассников и я собираемся сделать порт библиотеки комбинатора парсера Parsec для Haskell на Scala. (У него есть то преимущество перед встроенной-библиотекой синтаксического анализа Scala, что вы можете довольно легко передавать состояние, потому что все синтаксические анализаторы являются монадами.)

Первая заминка, с которой я столкнулся, это попытка выяснить, как Functor работает в scalaz. Кто-нибудь может объяснить, как преобразовать этот код на Haskell:

data Reply s u a = Ok a !(State s u) ParseError
                 | Error ParseError


instance Functor (Reply s u) where
    fmap f (Ok x s e) = Ok (f x) s e
    fmap _ (Error e) = Error e -- XXX

в Scala (, используя Scalaz, я полагаю). Я добрался до

sealed abstract class Reply[S, U, A]
case class Ok[S, U, A](a: A, state: State[S, U], error: ParseError)
    extends Reply[S, U, A]
case class Error[S, U, A](error: ParseError) extends Reply[S, U, A]

и знаю, что должен заставить Replyрасширить черту scalaz.Functor, но не могу понять, как это сделать. (В основном мне трудно понять, что делает параметр F[_].)

Приветствуется любая помощь!

Спасибо, Тодд

Основываясь на ответе dflemstr, я придумал этот:

sealed abstract class Reply[S, U, A]
object Reply {
  implicit def ReplyFunctor[S, U]  = {
    type ReplySU[A] = Reply[S, U, A]
    new Functor[ReplySU] {
      def fmap[A, B](r: ReplySU[A], f: A => B) = r match {
        case Ok(a, state, error) => Ok(f(a), state, error)
        case Error(error) => Error[S, U, B](error)
      }
    }
  }
}
case class Ok[S, U, A](a: A, state: State[S, U], error: ParseError) 
    extends Reply[S, U, A]()
case class Error[S, U, A](error: ParseError) extends Reply[S, U, A]()

В чем я не уверен, так это в ReplySU[A]типе. Фактический Functorв Haskell — это Reply s uс каррированными типами и отсутствующим типом a. Это то, как я должен делать то же самое в Scala, или я слишком усложняю?

7
задан TOB 1 April 2012 в 14:21
поделиться