Question about Nil and pattern matching

View: New views
10 Messages — Rating Filter:   Alert me  

Question about Nil and pattern matching

by jlist9 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi, I'm having a question with Nil and pattern matching.
The following code works:

val list = List()
list match {
  case Nil => "empty list"
  case x :: xs => "head:" + x + ", tail:" + xs
}

But if I replace List() with Nil, I get error:
constructor cannot be instantiated to expected type; found : ::[B]
required: object Nil

It looks like Nil is not equivalent to List(). If not, how come Nil
matches List()?

Re: Question about Nil and pattern matching

by Daniel Sobral :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Nil extends List, but List does not extend Nil.

On Sat, Oct 31, 2009 at 1:56 AM, jlist9 <jlist9@...> wrote:
Hi, I'm having a question with Nil and pattern matching.
The following code works:

val list = List()
list match {
 case Nil => "empty list"
 case x :: xs => "head:" + x + ", tail:" + xs
}

But if I replace List() with Nil, I get error:
constructor cannot be instantiated to expected type; found : ::[B]
required: object Nil

It looks like Nil is not equivalent to List(). If not, how come Nil
matches List()?



--
Daniel C. Sobral

Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.

Re: Question about Nil and pattern matching

by Randall Schulz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Friday October 30 2009, jlist9 wrote:

> Hi, I'm having a question with Nil and pattern matching.
> The following code works:
>
> val list = List()
> list match {
>   case Nil => "empty list"
>   case x :: xs => "head:" + x + ", tail:" + xs
> }
>
> But if I replace List() with Nil, I get error:
> constructor cannot be instantiated to expected type; found : ::[B]
> required: object Nil
>
> It looks like Nil is not equivalent to List(). If not, how come Nil
> matches List()?

To add a bit to Daniel's answer, if you change the declaration of
"val list" to include an explicit type annotation, your code will
compile:

val list: List[Whatever] = Nil
list match {
  case Nil => "empty list"
  case x :: xs => "head:" + x + ", tail:" + xs
}


Randall Schulz

Re: Question about Nil and pattern matching

by Ricky Clarkson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

For the same reason that:

val car = new Car

car match { case p: Potato => ... } is an error.

2009/10/31 jlist9 <jlist9@...>:

> Hi, I'm having a question with Nil and pattern matching.
> The following code works:
>
> val list = List()
> list match {
>  case Nil => "empty list"
>  case x :: xs => "head:" + x + ", tail:" + xs
> }
>
> But if I replace List() with Nil, I get error:
> constructor cannot be instantiated to expected type; found : ::[B]
> required: object Nil
>
> It looks like Nil is not equivalent to List(). If not, how come Nil
> matches List()?
>



--
Ricky Clarkson
Java and Scala Programmer, AD Holdings
+44 1565 770804
Skype: ricky_clarkson
Google Talk: ricky.clarkson@...
Google Wave: ricky.clarkson@...

Re: Question about Nil and pattern matching

by Alex Neth-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

As far as I know, Nil is equivalent to List(), not a subclass of List
as was suggested.  I can reproduce the error you get.  To my relative
newbie eye, it looks like a bug.

scala> Nil == List()
res23: Boolean = true

scala> val list = List()
list: List[Nothing] = List()

scala> list match { case Nil => "empty list"; case _ => "not empty list" }
res21: java.lang.String = empty list

scala> val list = Nil
list: Nil.type = List()

scala> list match { case Nil => "empty list"; case _ => "not empty list" }
res22: java.lang.String = empty list

scala> val list = Nil
list: Nil.type = List()

scala> list match { case List() => "empty list"; case _ => "not empty list" }
res25: java.lang.String = empty list

scala> Nil.getClass
res29: java.lang.Class[_] = class scala.Nil$

scala> List().getClass
res30: java.lang.Class[_] = class scala.Nil$


On Fri, Oct 30, 2009 at 8:56 PM, jlist9 <jlist9@...> wrote:

> Hi, I'm having a question with Nil and pattern matching.
> The following code works:
>
> val list = List()
> list match {
>  case Nil => "empty list"
>  case x :: xs => "head:" + x + ", tail:" + xs
> }
>
> But if I replace List() with Nil, I get error:
> constructor cannot be instantiated to expected type; found : ::[B]
> required: object Nil
>
> It looks like Nil is not equivalent to List(). If not, how come Nil
> matches List()?
>



--
Alex Neth
Liivid, Inc
www.liivid.com
+1 206 499 4995
+86 13761577188

Mike Ditka  - "If God had wanted man to play soccer, he wouldn't have
given us arms." -
http://www.brainyquote.com/quotes/authors/m/mike_ditka.html

Re: Question about Nil and pattern matching

by Viktor Klang :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Also:

scala> Nil eq List()
res0: Boolean = true


On Sat, Oct 31, 2009 at 10:50 AM, Alex Neth <alex@...> wrote:
As far as I know, Nil is equivalent to List(), not a subclass of List
as was suggested.  I can reproduce the error you get.  To my relative
newbie eye, it looks like a bug.

scala> Nil == List()
res23: Boolean = true

scala> val list = List()
list: List[Nothing] = List()

scala> list match { case Nil => "empty list"; case _ => "not empty list" }
res21: java.lang.String = empty list

scala> val list = Nil
list: Nil.type = List()

scala> list match { case Nil => "empty list"; case _ => "not empty list" }
res22: java.lang.String = empty list

scala> val list = Nil
list: Nil.type = List()

scala> list match { case List() => "empty list"; case _ => "not empty list" }
res25: java.lang.String = empty list

scala> Nil.getClass
res29: java.lang.Class[_] = class scala.Nil$

scala> List().getClass
res30: java.lang.Class[_] = class scala.Nil$


On Fri, Oct 30, 2009 at 8:56 PM, jlist9 <jlist9@...> wrote:
> Hi, I'm having a question with Nil and pattern matching.
> The following code works:
>
> val list = List()
> list match {
>  case Nil => "empty list"
>  case x :: xs => "head:" + x + ", tail:" + xs
> }
>
> But if I replace List() with Nil, I get error:
> constructor cannot be instantiated to expected type; found : ::[B]
> required: object Nil
>
> It looks like Nil is not equivalent to List(). If not, how come Nil
> matches List()?
>



--
Alex Neth
Liivid, Inc
www.liivid.com
+1 206 499 4995
+86 13761577188

Mike Ditka  - "If God had wanted man to play soccer, he wouldn't have
given us arms." -
http://www.brainyquote.com/quotes/authors/m/mike_ditka.html



--
Viktor Klang
| "A complex system that works is invariably
| found to have evolved from a simple system
| that worked." - John Gall

Blog: klangism.blogspot.com
Twttr: viktorklang
Code: github.com/viktorklang

Re: Question about Nil and pattern matching

by andrew cooke-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

i am not sure what you are looking at, but it clearly says here that
Nil is a subclass of List -
http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/scala/collection/immutable/List.html

andrew


2009/10/31 Alex Neth <alex@...>:

> As far as I know, Nil is equivalent to List(), not a subclass of List
> as was suggested.  I can reproduce the error you get.  To my relative
> newbie eye, it looks like a bug.
>
> scala> Nil == List()
> res23: Boolean = true
>
> scala> val list = List()
> list: List[Nothing] = List()
>
> scala> list match { case Nil => "empty list"; case _ => "not empty list" }
> res21: java.lang.String = empty list
>
> scala> val list = Nil
> list: Nil.type = List()
>
> scala> list match { case Nil => "empty list"; case _ => "not empty list" }
> res22: java.lang.String = empty list
>
> scala> val list = Nil
> list: Nil.type = List()
>
> scala> list match { case List() => "empty list"; case _ => "not empty list" }
> res25: java.lang.String = empty list
>
> scala> Nil.getClass
> res29: java.lang.Class[_] = class scala.Nil$
>
> scala> List().getClass
> res30: java.lang.Class[_] = class scala.Nil$
>
>
> On Fri, Oct 30, 2009 at 8:56 PM, jlist9 <jlist9@...> wrote:
>> Hi, I'm having a question with Nil and pattern matching.
>> The following code works:
>>
>> val list = List()
>> list match {
>>  case Nil => "empty list"
>>  case x :: xs => "head:" + x + ", tail:" + xs
>> }
>>
>> But if I replace List() with Nil, I get error:
>> constructor cannot be instantiated to expected type; found : ::[B]
>> required: object Nil
>>
>> It looks like Nil is not equivalent to List(). If not, how come Nil
>> matches List()?
>>
>
>
>
> --
> Alex Neth
> Liivid, Inc
> www.liivid.com
> +1 206 499 4995
> +86 13761577188
>
> Mike Ditka  - "If God had wanted man to play soccer, he wouldn't have
> given us arms." -
> http://www.brainyquote.com/quotes/authors/m/mike_ditka.html
>

Re: Question about Nil and pattern matching

by Paul Phillips-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, Oct 31, 2009 at 02:50:19AM -0700, Alex Neth wrote:
> As far as I know, Nil is equivalent to List(), not a subclass of List
> as was suggested.

case object Nil extends List[Nothing]

> I can reproduce the error you get.  To my relative newbie eye, it
> looks like a bug.

It is not a bug.  Look at the error:

> > constructor cannot be instantiated to expected type; found : ::[B]
> > required: object Nil

The scrutinee is of type Nil.type so reaching a pattern of class :: is
impossible.  List(), although it returns the object Nil, is typed to
return List[T] (which is a supertype of Nil.) Illustrating:

scala> Nil match { case Nil => true ; case _ :: _ => false }                    <console>:5: error: constructor cannot be instantiated to expected type;
 found   : ::[B]
 required: object Nil
       Nil match { case Nil => true ; case _ :: _ => false }
                                             ^

scala> (Nil: List[_]) match { case Nil => true ; case _ :: _ => false }
res1: Boolean = true

On Sat, Oct 31, 2009 at 10:55:44AM +0100, Viktor Klang wrote:
> scala> Nil eq List()
> res0: Boolean = true

Right, since List() returns Nil.

--
Paul Phillips      | Those who can make you believe absurdities
Everyman           | can make you commit atrocities.
Empiricist         |     -- Voltaire
slap pi uphill!    |----------* http://www.improving.org/paulp/ *----------

Re: Question about Nil and pattern matching

by Eastsun :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

+1

Paul Phillips-3 wrote:
On Sat, Oct 31, 2009 at 02:50:19AM -0700, Alex Neth wrote:
> As far as I know, Nil is equivalent to List(), not a subclass of List
> as was suggested.

case object Nil extends List[Nothing]

> I can reproduce the error you get.  To my relative newbie eye, it
> looks like a bug.

It is not a bug.  Look at the error:

> > constructor cannot be instantiated to expected type; found : ::[B]
> > required: object Nil

The scrutinee is of type Nil.type so reaching a pattern of class :: is
impossible.  List(), although it returns the object Nil, is typed to
return List[T] (which is a supertype of Nil.) Illustrating:

scala> Nil match { case Nil => true ; case _ :: _ => false }                    <console>:5: error: constructor cannot be instantiated to expected type;
 found   : ::[B]
 required: object Nil
       Nil match { case Nil => true ; case _ :: _ => false }
                                             ^

scala> (Nil: List[_]) match { case Nil => true ; case _ :: _ => false }
res1: Boolean = true

On Sat, Oct 31, 2009 at 10:55:44AM +0100, Viktor Klang wrote:
> scala> Nil eq List()
> res0: Boolean = true

Right, since List() returns Nil.

--
Paul Phillips      | Those who can make you believe absurdities
Everyman           | can make you commit atrocities.
Empiricist         |     -- Voltaire
slap pi uphill!    |----------* http://www.improving.org/paulp/ *----------
My scala solutions for Project Euler problems: Click here

Re: Question about Nil and pattern matching

by Naftoli Gugenheim :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Fri, Oct 30, 2009 at 11:56 PM, jlist9 <jlist9@...> wrote:
Hi, I'm having a question with Nil and pattern matching.
The following code works:

val list = List()
list match {
 case Nil => "empty list"
 case x :: xs => "head:" + x + ", tail:" + xs
}

But if I replace List() with Nil, I get error:
constructor cannot be instantiated to expected type; found : ::[B]
required: object Nil

It looks like Nil is not equivalent to List(). If not, how come Nil
matches List()?
 
If by the last line you were referring to
Nil match {
  case List() => ...
}
then it may be worth mentioning that "List()" can mean one of two things. Usually it is syntactic sugar for List.apply() where List is the List singleton object (in this case not inherently related to the List class). List.apply() returns Nil, so List() eq Nil.
On the other hand when the same syntax -- List() -- appears in a case pattern match statement: an extractor, it is syntactic sugar for List.unapply, or in this case List.unapplySeq (if I'm not mistaken), which is a comparison function. List() will pattern match Nil; List(x) will pattern match a single-element List and bind its element to x; List(X) or List(`x`) will patter match on a list containing exactly X or x respectively. Similar for more elements. List(x @ _*) will bind x to all of the list's 0 or more elements.