返回尝试或将来作为通用容器

时间:2016-09-12 13:56:54

标签: scala higher-kinded-types

我想切换到模式匹配样式,而不是在object JSONSourceLoaderUtil中使用重载方法。如何将结果Try[JValue]Future[JValue]处理为F[JValue]

进口和案例类

import scalaz._
import Scalaz._
import org.json4s.JsonAST.{JObject, JValue}

trait DataSource
case class LocalFile(input: File) extends DataSource
case class RemoteResource(url: String, req: JValue) extends DataSource

我现在拥有的,

object JSONSourceLoaderUtil {

  def jsonFrom[F[_], S <: DataSource](source: S)(f: S => F[JValue])(implicit ev: Monad[F]): F[JValue] = ev.bind(ev.point(source))(f)

  def extractFrom(source: RemoteResource): Future[JValue] = {
    Future( ... ).flatMap(input => Future.fromTry(Parser.parseFromChannel(Channels.newChannel(input))))
}

  def extractFrom(source: LocalFile): Try[JValue] = Parser.parseFromFile(source.input)
}

如何转换为模式匹配样式?如果我把自己画成一个角落,还有另一种方法吗?感谢。

object JSONSourceLoaderUtil {

def jsonFrom[F[_], S <: DataSource](source: S)(f: S => F[JValue])(implicit ev: Monad[F]): F[JValue] = ev.bind(ev.point(source))(f)

def extractFrom(source: DataSource): F[JValue] = source match {
    case RemoteResource(url, request) => Future( ... )
      .flatMap(input => Future.fromTry(Parser.parseFromChannel(Channels.newChannel(input))))) // cannot convert Future to F

    case LocalFile(input) => Parser.parseFromFile(input)  // cannot convert Try to F
  }
}

1 个答案:

答案 0 :(得分:0)

您想要的F取决于数据源的类型。那么为什么不明白呢?

trait DataSource[F[_]] {
  def extract: F[JValue]
}

case class LocalFile(input: File) extends DataSource[Try] {
  def extract = Parser.parseFromFile(input)
}

case class RemoteResource(url: String, req: JValue) extends DataSource[Future] {
  def extract = Future( ... )
    .flatMap(input => Future.fromTry(Parser.parseFromChannel(Channels.newChannel(input)))))
}

删除提取方法并编写

def extractFrom[F[_]](source: DataSource[F]): F[JValue] = source match {
    case RemoteResource(url, request) => Future( ... )
      .flatMap(input => Future.fromTry(Parser.parseFromChannel(Channels.newChannel(input)))))

    case LocalFile(input) => Parser.parseFromFile(input)
  }
}

也可能有效,at least in Scala 2.12。但我发现第一个解决方案更清洁。