Scala 中 ZipList 的应用实例
Applicative instance for ZipList in Scala
这是我最近的问题 的后续问题:
我想为 List
(可能 Set
和 Map
)定义一个 zip Applicative
实例。例如:
val xs: List[Int] = List(1, 2, 3)
val fs: List[Int => Int] = List(f1, f2, f3)
val ys: List[Int] = xs <*> fs // expected to be List(f1(1), f2(2), f3(3))
所以我定义了一个ZipList
和它的Applicative
:
case class ZipList[A](val list: List[A])
implicit val zipListApplicative = new Applicative[ZipList] {
def point[A](a: => A): ZipList[A] = ZipList(List(a))
def ap[A, B](za: => ZipList[A])(zf: => ZipList[A => B]): ZipList[B] = {
val bs = (za.list zip zf.list) map {case (a, f) => f(a)}
ZipList(bs)
}
}
并且可以如下使用:
scala> val xs: List[Int] = List(1, 2, 3)
xs: List[Int] = List(1, 2, 3)
scala> val fs: List[Int => Int] = List(_ + 2, _ + 2, _ +1)
fs: List[Int => Int] = List(<function1>, <function1>, <function1>)
scala> ZipList(xs) <*> ZipList(fs)
res4: ZipList[Int] = ZipList(List(3, 4, 4))
它似乎在工作,但也许我遗漏了什么。
zipListApplicative
是否遵守适用法律?
ZipList
是否应该是一个流,因为 point
应该生成一个无限的值流?为什么?
应用程序应符合法律
point identity <*> v == v
你的没有,因为
point identity List(1,2,3) == List(1)
pure a
对于 zip 列表应该 return 一个无限的 a
流,这就是为什么你需要一个惰性数据结构。
这是我最近的问题
我想为 List
(可能 Set
和 Map
)定义一个 zip Applicative
实例。例如:
val xs: List[Int] = List(1, 2, 3)
val fs: List[Int => Int] = List(f1, f2, f3)
val ys: List[Int] = xs <*> fs // expected to be List(f1(1), f2(2), f3(3))
所以我定义了一个ZipList
和它的Applicative
:
case class ZipList[A](val list: List[A])
implicit val zipListApplicative = new Applicative[ZipList] {
def point[A](a: => A): ZipList[A] = ZipList(List(a))
def ap[A, B](za: => ZipList[A])(zf: => ZipList[A => B]): ZipList[B] = {
val bs = (za.list zip zf.list) map {case (a, f) => f(a)}
ZipList(bs)
}
}
并且可以如下使用:
scala> val xs: List[Int] = List(1, 2, 3)
xs: List[Int] = List(1, 2, 3)
scala> val fs: List[Int => Int] = List(_ + 2, _ + 2, _ +1)
fs: List[Int => Int] = List(<function1>, <function1>, <function1>)
scala> ZipList(xs) <*> ZipList(fs)
res4: ZipList[Int] = ZipList(List(3, 4, 4))
它似乎在工作,但也许我遗漏了什么。
zipListApplicative
是否遵守适用法律?ZipList
是否应该是一个流,因为point
应该生成一个无限的值流?为什么?
应用程序应符合法律
point identity <*> v == v
你的没有,因为
point identity List(1,2,3) == List(1)
pure a
对于 zip 列表应该 return 一个无限的 a
流,这就是为什么你需要一个惰性数据结构。