2016-07-30 5 views
4

Глядя на отличном блоге Трэвиса Брауна на Type classes and generic derivation, я вижу следующий метод:Значение `::` в параметре типа?

implicit def hconsParser[H: Parser, T <: HList: Parser]: Parser[H :: T] =   
    new Parser[H :: T] { 
    def apply(s: String): Option[H :: T] = s.split(",").toList match { 
     case cell +: rest => for { 
     head <- implicitly[Parser[H]].apply(cell) 
     tail <- implicitly[Parser[T]].apply(rest.mkString(",")) 
     } yield head :: tail 
    } 
    } 

Что смысл H :: T в Parser[H :: T]?

Кроме того, как это case cell +: rest обрабатывают случай, когда s, то есть ввод apply пуст?

ответ

9

H :: T является инфиксной формой типа ::[H, T], который является HList с головкой типа H и хвостом типа T <: HList. т. е. мы ищем Parser для типа ::[H, T].

Использование инфикса достигается, как это, где infix может быть любым именем:

scala> trait infix[A, B] 

scala> def test[A, B](ab: A infix B) = ??? 
test: [A, B](ab: infix[A,B])Nothing 

Кроме того, как это case cell +: rest обрабатывает случай, когда s, т.е. вход apply пуст?

Если s пустая строка, то s.split(",").toList просто будет List с пустой строкой в ​​качестве его единственного элемента. case cell +: rest никогда не будет запущен в пустой список.