scala – monad变压器是否适用于从服务中获取JSON?
我有一个玩! 2用于需要从外部服务检索JSON格式的一些数据的Scala应用程序。
表演!框架允许通过在Promise中包含响应异步地进行HTTP请求。Promise是一个包含将来可用的值的monad。 这是很好的,但在我的情况下,我从Web服务获得的是一个JSON字符串。我必须解析它,解析可能会失败。所以我必须把任何我进入一个选项。结果是我的很多方法都返回了Promise [Option [Whatever]]。也就是说,值的类型不管会是什么,也许稍后可用。 现在每当我必须操作这样一个价值,我需要映射两次。我正在考虑以下列方式处理: >创建一个新的类型,希望[A],包裹承诺[选项[A]] 很容易定义地图 – 两个函子的组合又是一个函子 – 在这种情况下,或者在使用Option构成单元时,可以明确地进行平坦化。 但是我有限的理解是,我不需要重新发明这个东西:正是这种情况存在monad变压器。或者,所以我想 – 我从来没有使用过一个monad转换器 – 这是问题的要点:
解决方法
使用Scalaz库的OptionT变压器,您应该可以将Promise [Option [A]]类型的值转换为OptionT [Promise,A]类型的值。
使用Scalaz 7: import scalaz.OptionT._ val x: OptionT[Promise,Int] = optionT(Promise.pure(Some(123))) 要使用此值,例如在其上调用map或flatMap,您将需要为Promise(Functor for Map,Monad for flatMap)提供适当的类型类。 由于承诺是单一的,应该可以提供一个Monad [Promise]的例子。 (你会得到免费的Functor和Applicative,因为类型类形成一个继承层次结构。)例如(注意:我还没有测试过!): implicit val promiseMonad = new Monad[Promise] { def point[A](a: => A): Promise[A] = Promise.pure(a) def bind[A,B](fa: Promise[A])(f: A => Promise[B]): Promise[B] = fa flatMap f } 作为一个简单的例子,现在可以使用OptionT [Promise,A]上的map来应用类型为A =>的函数B到里面的价值: def foo[A,B](x: OptionT[Promise,A],f: A => B): OptionT[Promise,B] = x map f 要从OptionT [Promise,A]中检索底层的Promise [Option [A]]值,请调用run方法。 def bar[A,B](x: Promise[Option[A]],f: A => B): Promise[Option[B]] = optionT(x).map(f).run 当您可以组合兼容类型的多个操作时,使用单变形变压器可以获得更多的收益,在操作之间保留OptionT [Promise,_]类型并在最后检索基础值。 要以理解方式组合操作,您将需要A =>类型的函数。 OptionT [承诺,B]。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |