ZipList与Scalaz [英] ZipList with Scalaz

查看:81
本文介绍了ZipList与Scalaz的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个数字列表和一个函数列表:

Suppose I have a list of numbers and list of functions:

val xs: List[Int] = List(1, 2, 3)
val fs: List[Int => Int] = List(f1, f2, f3)

现在我想使用Applicativef1应用于1,将f2应用于2,等等.

Now I would like to use an Applicative to apply f1 to 1, f2 to 2, etc.

val ys: List[Int] = xs <*> fs // expect List(f1(1), f2(2), f3(3))

如何使用Scalaz来做到这一点?

How can I do it with Scalaz ?

推荐答案

pure会永远重复该值,因此无法为Scala的List(或类似列表的东西)定义一个zippy应用实例. . Scalaz确实为Stream和适当的zippy应用实例提供了Zip标记,但据我所知它仍然很破损.例如,这将不起作用(但应该):

pure for zip lists repeats the value forever, so it's not possible to define a zippy applicative instance for Scala's List (or for anything like lists). Scalaz does provide a Zip tag for Stream and the appropriate zippy applicative instance, but as far as I know it's still pretty broken. For example, this won't work (but should):

import scalaz._, Scalaz._

val xs = Tags.Zip(Stream(1, 2, 3))
val fs = Tags.Zip(Stream[Int => Int](_ + 3, _ + 2, _ + 1))

xs <*> fs

您可以直接使用应用实例(如在其他答案中一样),但是拥有语法很好,并且编写真实的"(即未标记的)包装器也不太困难.例如,这是我使用的解决方法:

You can use the applicative instance directly (as in the other answer), but it's nice to have the syntax, and it's not too hard to write a "real" (i.e. not tagged) wrapper. Here's the workaround I've used, for example:

case class ZipList[A](s: Stream[A])

import scalaz._, Scalaz._, Isomorphism._

implicit val zipListApplicative: Applicative[ZipList] =
  new IsomorphismApplicative[ZipList, ({ type L[x] = Stream[x] @@ Tags.Zip })#L] {
    val iso =
      new IsoFunctorTemplate[ZipList, ({ type L[x] = Stream[x] @@ Tags.Zip })#L] {
        def to[A](fa: ZipList[A]) = Tags.Zip(fa.s)
        def from[A](ga: Stream[A] @@ Tags.Zip) = ZipList(Tag.unwrap(ga))
      }
    val G = streamZipApplicative
  }

然后:

scala> val xs = ZipList(Stream(1, 2, 3))
xs: ZipList[Int] = ZipList(Stream(1, ?))

scala> val fs = ZipList(Stream[Int => Int](_ + 10, _ + 11, _ + 12))
fs: ZipList[Int => Int] = ZipList(Stream(<function1>, ?))

scala> xs <*> fs
res0: ZipList[Int] = ZipList(Stream(11, ?))

scala> res0.s.toList
res1: List[Int] = List(11, 13, 15)

对于它的价值而言,似乎已被至少几年.

For what it's worth, it looks like this has been broken for at least a couple of years.

这篇关于ZipList与Scalaz的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆