Один из моих старшеклассников и я попытаемся сделать порт библиотеки комбинатора парсеров Parsec на Haskell в Scala.(По сравнению со встроенной библиотекой разбора Scala у нее есть преимущество, заключающееся в том, что вы можете довольно легко передавать состояние, потому что все анализаторы являются монадами.)
Первое, с чем я столкнулся, пытается выяснить, как работает Functor.в скалазе.Может кто-нибудь объяснить, как преобразовать этот код на 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 или я слишком усложняю вещи?