如何将Haskell翻译成Scalaz?
我的一个高中生和我将尝试将一个
Haskell的Parsec解析器组合库移植到
Scala中. (它比
Scala的内置解析库更有优势,你可以相当容易地传递状态,因为所有的解析器都是monad.)
我遇到的第一个故障是试图弄清楚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,A](a: A,state: State[S,U],error: ParseError) extends Reply[S,A] case class Error[S,A](error: ParseError) extends Reply[S,A] 并知道我应该回复扩展scalaz.Functor特性,但我无法弄清楚如何做到这一点. (大多数情况下,我无法弄清楚F [_]参数的作用.) 任何帮助赞赏! 谢谢, 根据dflemstr的回答,我想出了这个: sealed abstract class Reply[S,A] object Reply { implicit def ReplyFunctor[S,U] = { type ReplySU[A] = Reply[S,A] new Functor[ReplySU] { def fmap[A,B](r: ReplySU[A],f: A => B) = r match { case Ok(a,state,error) => Ok(f(a),error) case Error(error) => Error[S,B](error) } } } } case class Ok[S,error: ParseError) extends Reply[S,A]() case class Error[S,A]() 我不确定的是ReplySU [A]类型. Haskell中的实际Functor是使用curried类型回复s和缺少的类型.这是我在Scala中应该做同样的事情还是我过于复杂的事情? 解决方法
在Functor [F [_]]中,F表示它是一个类型构造函数,即参数化类型,必须将其他类型作为参数才能成为完全限定类型.例如,如果F是List,则List [Int]是该参数化类型的类型实例.
因此,当您定义Functor [List]类型的值时,它意味着它是一个描述Lists函子性质的对象,并且functor对象将使用高阶类型List来构造各种类型实例,例如List [ A]和列表[B]. 此外,您必须了解Scala的类和Haskell类之间的区别. Haskell中的类实例最好用Scala中的隐式值建模,而不是接口的实现;虽然您需要一个对象的实例在Java / Scala中也有一个接口实例,但您可以在Haskell中拥有一个类的实例,而不需要该类处理的值类型的实例. 例如,想象一下如何从Scala中的Haskell实现 相反,您创建一个单独的ReadFoo:Read [Foo]对象,其中包含类型为Foo的Read函数的实现.然后你可以调用ReadFoo.read(string:String):Foo并安全地返回Foo类型. 对于仿函数实例,您需要的是以下内容: // All implicits in the companion object of Reply are automatically brought into // scope when Reply is imported object Reply { // Describes how to treat a `Reply` as a functor implicit val ReplyFunctor: Functor[Reply] = new Functor[Reply] { def fmap[A,B](r: Reply[A],f: A => B) = r match { case Ok(x,s,e) => Ok(f(x),e) case err => err // leave value unchanged } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |