如何模式匹配scala列表的头部和尾部类型? [英] How to pattern match head and tail types of a scala list?

查看:44
本文介绍了如何模式匹配scala列表的头部和尾部类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对 head 类型的 scalalist 的不同段进行 pattern match> 和 tail:

I would like to pattern match on different segments of a list in scala on the types of the head and tail:

class Solution07 extends FlatSpec with ShouldMatchers {
  "plain recursive flatten" should "flatten a list" in {
    val list1 = List(List(1, 1), 2, List(3, List(5, 8)))
    val list1Flattened = List(1, 1, 2, 3, 5, 8)

    flattenRecur(list1) should be (list1Flattened)
  }

  def flattenRecur(ls: List[Any]): List[Int] = ls match {
    case (head: Int) :: (tail: List[Any]) => head :: flattenRecur(tail)
    case (head: List[Int]) :: (tail: List[Any]) => head.head :: flattenRecur(head.tail :: tail)
    case (head: List[Any]) :: (tail: List[Any]) => flattenRecur(head) :: flattenRecur(tail) // non-variable type... on this line.
  }
}

我明白了:

错误:(18, 17) 类型模式中的非变量类型参数 IntList[Int](List[Int] 的底层)未选中,因为它是通过擦除消除case (head: List[Int]) :: (tail: List[Any]) => head.head :: flattenRecur(head.tail :: tail)^

Error:(18, 17) non-variable type argument Int in type pattern List[Int] (the underlying of List[Int]) is unchecked since it is eliminated by erasure case (head: List[Int]) :: (tail: List[Any]) => head.head :: flattenRecur(head.tail :: tail) ^

我错过了什么?我怎么可能对列表的 headtailtypes 进行模式匹配?

What am I missing? how is it possible for me to pattern match on the head and tail's types of the list?

推荐答案

我同意 @Andreas 使用 HList 的解决方案是解决问题的一个很好的例子,但我仍然不明白这有什么问题:

I agree that @Andreas solution with HList is a nice example for solving the problem, but I still do not understand what's the problem with this:

 def flatten(ls: List[_]): List[Int] = ls match {
    case Nil => Nil
    case (a: Int) :: tail => a :: flatten(tail)
    case (a: List[_]) :: tail => flatten(a) ::: flatten(tail)
    case _ :: tail => flatten(tail)
  }

那么:

println(flatten(List(List("one",9,8),3,"str",4,List(true,77,3.2)))) // List(9, 8, 3, 4, 77)

我在您的任务中没有发现类型擦除有任何问题,因为您实际上不需要测试被擦除的类型.在我的示例中,我有意跳过了所有已擦除的类型 - 以显示这一点.类型擦除不会清除列表元素的类型信息,它只清除列表泛型的类型信息,在我的情况下,您拥有 Any_ - 所以你根本不需要那个.如果我没有遗漏一些东西,那么在您的示例中,类型根本不会被删除,因为无论如何您几乎到处都有 Any.

I don't see any problems with type erasure in your task, because you actually don't need to test the types that are erased. I've intentionally skipped all erased types in my example - to show this. Type erasure does not clear the type information of the elements of the list, it clears only the type information of list generic which you have Any or _ in my case - so you do not need that at all. If I am not missing someting, in your example the types are not erased at all, because you anyway have Any almost everywhere.

这篇关于如何模式匹配scala列表的头部和尾部类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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