如何删除显式铸造

时间:2018-06-26 16:39:39

标签: scala

如何在Cons(f(a), b).asInstanceOf[XList[B]]函数内的map中删除显式强制转换 asInstanceOf [XList [B]] ?还是重新设计reducemap函数?谢谢

trait XList[+A]
case object Empty extends XList[Nothing]
case class Cons[A](x: A, xs: XList[A]) extends XList[A]

object XList {
  def apply[A](as: A*):XList[A] = if (as.isEmpty) Empty else Cons(as.head, apply(as.tail: _*))
  def empty[A]: XList[A] = Empty
}

def reduce[A, B](f: B => A => B)(b: B)(xs: XList[A]): B = xs match {
  case Empty => b
  case Cons(y, ys) => reduce(f)(f(b)(y))(ys)
}

def map[A, B](f: A => B)(xs: XList[A]): XList[B] = reduce((b: XList[B]) => (a: A) => Cons(f(a), b).asInstanceOf[XList[B]])(XList.empty[B])(xs)

2 个答案:

答案 0 :(得分:1)

您可以将)(替换为,,将两个参数列表合并为一个:

def reduce[A, B](f: B => A => B, b: B)(xs: XList[A]): B = xs match {
  case Empty => b
  case Cons(y, ys) => reduce(f, f(b)(y))(ys)
}

def map[A, B](f: A => B)(xs: XList[A]): XList[B] = 
  reduce((b: XList[B]) => (a: A) => Cons(f(a), b), XList.empty[B])(xs)

这将迫使类型推断算法在决定reduce应该是什么之前先考虑B的两个第一个参数。

答案 1 :(得分:0)

通过显式提供类型参数,您可以在呼叫站点将Cons扩展为XList[B]

def map[A, B](f: A => B)(xs: XList[A]): XList[B] =
  reduce[A, XList[B]]((b: XList[B]) => (a: A) => Cons(f(a), b))(XList.empty[B])(xs)

或使用类型说明:

def map[A, B](f: A => B)(xs: XList[A]): XList[B] =
  reduce((b: XList[B]) => (a: A) => Cons(f(a), b): XList[B])(XList.empty[B])(xs)

请注意,reduce在方法定义上通常比您编写的要严格。减少通常看起来像这样:

def reduce[A](a0: A, a: A): A

首先需要一个非空的集合。您实现的内容与foldLeft的结构类似(具有这种结构(来自Scalas集合库)):

def foldLeft[B](z: B)(op: (B, A) => B): B