2016-10-27 3 views
0

лестницу я получаю следующую ошибку компиляции времени в коде нижеЧто случилось со следующим кодом

Ошибка: (7, 29), не было найдено: значение Cons

Защиту :: [B>: а] (головка: в) = Против [B] (голова, это)

package basics 

sealed trait List[+A] { 

    import Types._ 

    def ::[B >: A](head: B) = Cons[B](head, this) 

    def foreach(f: A => Unit): Unit = { 
    this match { 
     case x :: t => { 
     f(x) 
     t foreach f 
     } 
     case Nil =>() 
    } 
    } 

} 

object Types { 
    type Cons[A] = ::[A] 
} 
case class ::[+A](head: A, tail: List[A]) extends List[A] 
object Nil extends List[Nothing] 


object Application { 

    def main(args: Array[String]): Unit ={ 
    println("hello") 

    3 :: Nil 
    } 
} 
+1

Попробуйте 'Типы. Концы'. Вы отправляете неправильный код. Это ':: [B] (head, this)' в вашем примере. – talex

+0

@talex Редактирует код. Также Type.Cons имеет ту же проблему –

ответ

2

Против является псевдонимом не является значением. Это не может произойти на позиция значения. Например:

Я сделал несколько изменений в программу, чтобы сделать его работу:

case class ::[+A](head: A, tail: List[A]) extends List[A] 
object Nil extends List[Nothing] 

object Types { 
    type Cons[A] = ::[A] 
    def cons[A](head: A, tail: List[A]) = ::(head,tail) 
} 

sealed trait List[+A] { 
    import Types._ 

    def ::[B >: A](head: B):Cons[B] = cons[B](head, this) 
} 

В def ::[B >: A](head: B):Cons[B] = cons[B](head, this), :Cons[B] иллюстрирует один правильный вариант использования типа с псевдонимом.

Еще одна проблема с вашей программой является наличие двух :: перегруженных символов в той же области, поэтому она требует создания Types.cons, в противном случае компилятор Scala думает, что мы пытаемся вызвать List#::

Вот пример от РЕПЛ:

scala> 3 :: Nil 
res0: Types.Cons[Int] = ::(3,[email protected]) 

scala> 3 :: 4 :: Nil 
res1: Types.Cons[Int] = ::(3,::(4,[email protected])) 

Смотрите тип выражений является Cons[Int].

1

причина заключается в том, что

object Types { 
    type Cons[A] = ::[A] 
} 

является декларация типа, но Cons in

def ::[B >: A](head: B) = Cons[B](head, this) 

- ссылка на конструктор. Если вы замените его ссылкой на фактический конструктор.

Добавить метод def Cons[A] = ::[A] в Types и все будет работать нормально.

0

Лучшей альтернативой определению def Cons[A] = ::[A] является val Cons = ::. Это позволяет не только писать Cons[B](head, this), но соответствующий шаблон

this match { 
    case Cons(x, t) => ... 
    case Nil => ... 
} 

и доступ к любым другим методам, определенным на объекте :: компаньона, используя Cons имя. Это также то, что стандартная библиотека Scala does:

type Map[A, +B] = immutable.Map[A, B] 
type Set[A]  = immutable.Set[A] 
val Map   = immutable.Map 
val Set   = immutable.Set 
Смежные вопросы