# Why Set aren't covariant

55 replies
vpatryshev
Joined: 2009-02-16,
Re: Why Set aren't covariant
That's an logically-sounding restriction; but seems like it is not necessary.

2009/7/29 John Nilsson <john [at] milsson [dot] nu>
On Wed, Jul 29, 2009 at 12:52 AM, Tony Morris<tonymorris [at] gmail [dot] com> wrote:
> scala> val p = forAll { (s: collection.Set[Int], f: Int => String, g:
> Int => Int) => (s map g map f) == s.map(f compose g) }

Hmm, would it solve the problem if you require the argument to map to
be injective for sets?

BR,
John

--
Thanks,
John Nilsson
Joined: 2008-12-20,
Re: Why Set aren't covariant

Hmm, maybe it is.

class Value(val id:Int,val aux:Int)
{
override def equals(that:Any) = that.isInstanceOf[Value] &&
this.id == that.asInstanceOf[Value].id
override def toString = id + " -> " + aux
}

def main(args:Array[String]):Unit = {
val s = Set(new Value(2,1),new Value(4,2))

val f = (v:Value) => new Value(v.id % 2, v.aux)
val g = (v:Value) => new Value(v.aux, v.id)

println(s map f map g)
println(s map (g compose f))
}

>>>>

Set(1 -> 0)
Set(1 -> 0, 2 -> 0)

BR,
John

On Wed, Jul 29, 2009 at 9:00 PM, Vlad Patryshev wrote:
> That's an logically-sounding restriction; but seems like it is not
> necessary.
>
> 2009/7/29 John Nilsson
>>
>> On Wed, Jul 29, 2009 at 12:52 AM, Tony Morris wrote:
>> > scala> val p = forAll { (s: collection.Set[Int], f: Int => String, g:
>> > Int => Int) => (s map g map f) == s.map(f compose g) }
>>
>> Hmm, would it solve the problem if you require the argument to map to
>> be injective for sets?
>>
>> BR,
>> John
>
>
>
> --
> Thanks,
>

vpatryshev
Joined: 2009-02-16,
Re: Why Set aren't covariant
This is a cool example... but wait, s map f gives Set(0->1, 0->2), which is illegal as a Set; and I can't figure out what's broken here.

2009/7/29 John Nilsson <john [at] milsson [dot] nu>
Hmm, maybe it is.

class Value(val id:Int,val aux:Int)
{
override def equals(that:Any) = that.isInstanceOf[Value] &&
this.id == that.asInstanceOf[Value].id
override def toString = id + " -> " + aux
}

def main(args:Array[String]):Unit = {
val s = Set(new Value(2,1),new Value(4,2))

val f = (v:Value) => new Value(v.id % 2, v.aux)
val g = (v:Value) => new Value(v.aux, v.id)

println(s map f map g)
println(s map (g compose f))
}

>>>>

Set(1 -> 0)
Set(1 -> 0, 2 -> 0)

BR,
John

On Wed, Jul 29, 2009 at 9:00 PM, Vlad Patryshev<vpatryshev [at] gmail [dot] com> wrote:
> That's an logically-sounding restriction; but seems like it is not
> necessary.
>
> 2009/7/29 John Nilsson <john [at] milsson [dot] nu>
>>
>> On Wed, Jul 29, 2009 at 12:52 AM, Tony Morris<tonymorris [at] gmail [dot] com> wrote:
>> > scala> val p = forAll { (s: collection.Set[Int], f: Int => String, g:
>> > Int => Int) => (s map g map f) == s.map(f compose g) }
>>
>> Hmm, would it solve the problem if you require the argument to map to
>> be injective for sets?
>>
>> BR,
>> John
>
>
>
> --
> Thanks,
>

--
Thanks,
John Nilsson
Joined: 2008-12-20,
Re: Why Set aren't covariant

Works for me (Scala 2.7 something for NetBeans, no imports)

println(s map f)
>>>
Set(0 -> 1)

BR,
John

On Thu, Jul 30, 2009 at 7:45 AM, Vlad Patryshev wrote:
> This is a cool example... but wait, s map f gives Set(0->1, 0->2), which is
> illegal as a Set; and I can't figure out what's broken here.
>
> 2009/7/29 John Nilsson
>>
>> Hmm, maybe it is.
>>
>>    class Value(val id:Int,val aux:Int)
>>    {
>>        override def equals(that:Any) = that.isInstanceOf[Value] &&
>> this.id == that.asInstanceOf[Value].id
>>        override def toString = id + " -> " + aux
>>    }
>>
>>    def main(args:Array[String]):Unit = {
>>        val s = Set(new Value(2,1),new Value(4,2))
>>
>>        val f = (v:Value) => new Value(v.id % 2, v.aux)
>>        val g = (v:Value) => new Value(v.aux, v.id)
>>
>>        println(s map f map g)
>>        println(s map (g compose f))
>>    }
>>
>> >>>>
>>
>> Set(1 -> 0)
>> Set(1 -> 0, 2 -> 0)
>>
>>
>> BR,
>> John
>>
>>
>> On Wed, Jul 29, 2009 at 9:00 PM, Vlad Patryshev
>> wrote:
>> > That's an logically-sounding restriction; but seems like it is not
>> > necessary.
>> >
>> > 2009/7/29 John Nilsson
>> >>
>> >> On Wed, Jul 29, 2009 at 12:52 AM, Tony Morris
>> >> wrote:
>> >> > scala> val p = forAll { (s: collection.Set[Int], f: Int => String, g:
>> >> > Int => Int) => (s map g map f) == s.map(f compose g) }
>> >>
>> >> Hmm, would it solve the problem if you require the argument to map to
>> >> be injective for sets?
>> >>
>> >> BR,
>> >> John
>> >
>> >
>> >
>> > --
>> > Thanks,
>> >
>
>
>
> --
> Thanks,
>

vpatryshev
Joined: 2009-02-16,
Re: Why Set aren't covariant
Sorry, but with this definition of equals in Value, g is not a function:Value(0,1) == Value(0,2), but g(Value(0, 1) != g(Value(0, 2)).
This may bring a bigger discussion regarding how functions should preserve equality, but anyway, this example does not seem valid to me.

2009/7/29 John Nilsson <john [at] milsson [dot] nu>
Hmm, maybe it is.

class Value(val id:Int,val aux:Int)
{
override def equals(that:Any) = that.isInstanceOf[Value] &&
this.id == that.asInstanceOf[Value].id
override def toString = id + " -> " + aux
}

def main(args:Array[String]):Unit = {
val s = Set(new Value(2,1),new Value(4,2))

val f = (v:Value) => new Value(v.id % 2, v.aux)
val g = (v:Value) => new Value(v.aux, v.id)

println(s map f map g)
println(s map (g compose f))
}

>>>>

Set(1 -> 0)
Set(1 -> 0, 2 -> 0)

BR,
John

On Wed, Jul 29, 2009 at 9:00 PM, Vlad Patryshev<vpatryshev [at] gmail [dot] com> wrote:
> That's an logically-sounding restriction; but seems like it is not
> necessary.
>
> 2009/7/29 John Nilsson <john [at] milsson [dot] nu>
>>
>> On Wed, Jul 29, 2009 at 12:52 AM, Tony Morris<tonymorris [at] gmail [dot] com> wrote:
>> > scala> val p = forAll { (s: collection.Set[Int], f: Int => String, g:
>> > Int => Int) => (s map g map f) == s.map(f compose g) }
>>
>> Hmm, would it solve the problem if you require the argument to map to
>> be injective for sets?
>>
>> BR,
>> John
>
>
>
> --
> Thanks,