Tony Morris | 1 Jul 2012 01:31
Picon

Re: Why is the PECS principle not applied to Function1?

I'm pretty sure that compose is a method on A => B taking an argument of
the type X => A and return a value of the type X => B, hence
compose/map: (A => B) => (X => A) => (X => B).

On 01/07/12 00:51, Chris Marshall wrote:
> You also got compose and andThen the wrong way round. g(f(x)) is  (f andThen g)(x) or (g compose f)(x). Hence
>  - andThen is "map" - compose is "contra-map"
> Chris
>> Date: Sat, 30 Jun 2012 21:02:02 +1000
>> From: tonymorris@...
>> To: scala-user@...
>> Subject: Re: [scala-user] Why is the PECS principle not applied to Function1?
>>
>> On 30/06/12 20:49, Tony Morris wrote:
>>> As for contravariance, we have a very similar question. First, what is a
>>> contravariant functor? It is any functor giving rise to this operation:
>>> [A, B](A => B) => F[B] => F[B]
>> Sorry, typo.
>>
>> The correct signature for contravariance is:
>> [A, B](A => B) => F[B] => F[A]
>>
>> PS: I sometimes wonder if spell-correctors of the future will pick that
>> up, "you just wrote a function signature that is  not very useful. Did
>> you mean to write this instead...?"
>>
>> -- 
>> Tony Morris
>> http://tmorris.net/
>>
(Continue reading)

Josh Suereth | 1 Jul 2012 01:32
Picon
Gravatar

Re: Covariance contravariance help

Make your vars private and that helps.  We don't have thorough effect tracking for crazier variance rules. 

Just remember a public var is something *anyone* can get/set.   That's very bad for variance.   Hence scala limiting invariance for such things.

On Jun 30, 2012 6:56 PM, "Haoyi Li" <haoyi.sg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
I'm trying to make a simple reactive system. I have Emitters (which give off pulses) and Reactors (which take in pulses).

I want my Emitters to be covariant: If I need something giving off pulses of type T, then something giving of pulses of R <: T should work. Similarly, my reactors should be contravariant, since i should always be able to substitute in something which takes in a broader range of pulses. 

Lastly, they should each have a mutable list of their counterparts: an emitter keeps track of the reactors listening to it, and a reactor keeps track of the emitters it's listening to.

The code I have looks like this:

trait Emitter[+T]{
  var reactors: Seq[Reactor[T]] = Seq()
}

trait Reactor[-T]{
  var emitters: Seq[Emitter[T]] = Seq()
  def ping(t: T);
}

However, it doesn't work because of co/contravariance problems from the mutable `var`s. I've played with it a while and thought about it and haven't manage to come up with a formulation that will satisfy the typechecker.

I *think* what i'm trying to do makes sense. Is there some correct way of representing these that type-checks, or is my approach simply unsound?

Thanks!
-Haoyi
Haoyi Li | 1 Jul 2012 07:37
Picon

Re: Covariance contravariance help

Even with private vars:


trait Emitter[+T]{
  private var reactors: Seq[Reactor[T]] = Seq()
}

trait Reactor[-T]{
  private var emitters: Seq[Emitter[T]] = Seq()
}

the typechecker still won't let me do it (covariant type in contravariant position etc.); I think it's because of the circular type-reference? I'm not entirely clear.

I'm trying to follow Ingo Maier's implementation of Scala.React, which uses a mutable, dynamically generated (and regenerated) dependency tree, which is why I need the mutability. I'm still not entirely sure how *he* structures his co/contravariance and how (or even if) he solves this problem; I have his code working, but haven't figured it out yet.

On Sat, Jun 30, 2012 at 4:32 PM, Josh Suereth <joshua.suereth-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

Make your vars private and that helps.  We don't have thorough effect tracking for crazier variance rules. 

Just remember a public var is something *anyone* can get/set.   That's very bad for variance.   Hence scala limiting invariance for such things.

On Jun 30, 2012 6:56 PM, "Haoyi Li" <haoyi.sg-Re5JQEeQqe8@public.gmane.orgm> wrote:
I'm trying to make a simple reactive system. I have Emitters (which give off pulses) and Reactors (which take in pulses).

I want my Emitters to be covariant: If I need something giving off pulses of type T, then something giving of pulses of R <: T should work. Similarly, my reactors should be contravariant, since i should always be able to substitute in something which takes in a broader range of pulses. 

Lastly, they should each have a mutable list of their counterparts: an emitter keeps track of the reactors listening to it, and a reactor keeps track of the emitters it's listening to.

The code I have looks like this:

trait Emitter[+T]{
  var reactors: Seq[Reactor[T]] = Seq()
}

trait Reactor[-T]{
  var emitters: Seq[Emitter[T]] = Seq()
  def ping(t: T);
}

However, it doesn't work because of co/contravariance problems from the mutable `var`s. I've played with it a while and thought about it and haven't manage to come up with a formulation that will satisfy the typechecker.

I *think* what i'm trying to do makes sense. Is there some correct way of representing these that type-checks, or is my approach simply unsound?

Thanks!
-Haoyi

Jason Zaugg | 1 Jul 2012 08:04
Picon
Gravatar

Re: Covariance contravariance help

On Sun, Jul 1, 2012 at 7:37 AM, Haoyi Li <haoyi.sg@...> wrote:
> Even with private vars:
>
> trait Emitter[+T]{
>   private var reactors: Seq[Reactor[T]] = Seq()
> }
>
> trait Reactor[-T]{
>   private var emitters: Seq[Emitter[T]] = Seq()
> }
>
> the typechecker still won't let me do it (covariant type in contravariant
> position etc.); I think it's because of the circular type-reference? I'm not
> entirely clear.
>
> I'm trying to follow Ingo Maier's implementation of Scala.React, which uses
> a mutable, dynamically generated (and regenerated) dependency tree, which is
> why I need the mutability. I'm still not entirely sure how *he* structures
> his co/contravariance and how (or even if) he solves this problem; I have
> his code working, but haven't figured it out yet.

They must be private[this] to keep things sound.

-jason

Naftoli Gugenheim | 1 Jul 2012 08:22
Picon
Gravatar

Re: Recommended/possible to use syntactic sugar for typeclasses


On Fri, Jun 29, 2012 at 1:53 PM, Erik Osheim <erik-RrIVv6Yi33f3y/S9aNj6cVaTQe2KTcn/@public.gmane.org> wrote:
On Fri, Jun 29, 2012 at 07:25:26PM +0200, zeec-hi6Y0CQ0nG0@public.gmane.org wrote:
> If possible, I would like to add some syntactic sugar or a kind of
> alias to represent the definition of a typeclass (ideally as close as
> possible to the syntax in Haskell). Do you think that would make sense,
> make it easier to read sources or just confuse?
>
> I don't know it is possible with Scala 2.9, but it should be with the
> introduction of macros. (?)

Hi Manuel,

I don't think macros will be able to solve this problem. From what I
understand, macros are good at changing one expression's AST into
another one, but are not good for generating code for new classes,
objects or methods that weren't previously there

... yet. It's planned for the future though.

 

I know Josh Suereth has been working hard to try to make this pattern
require less boilerplate, and 2.10 has some features which do help
(i.e. implicit classes).

But there's still a lot of ceremony, unfortunately.

-- Erik

Haoyi Li | 1 Jul 2012 08:46
Picon

Re: Covariance contravariance help

Thanks, that nailed it! This compiles:


trait Emitter[+T]{
  private[this] var children: Seq[Reactor[T]] = Seq()
}

trait Reactor[-T]{
  private[this] var parents: Seq[Emitter[T]] = Seq()
}

Progress has been made!
Thanks!
-Haoyi


On Sat, Jun 30, 2012 at 11:04 PM, Jason Zaugg <jzaugg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
On Sun, Jul 1, 2012 at 7:37 AM, Haoyi Li <haoyi.sg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Even with private vars:
>
> trait Emitter[+T]{
>   private var reactors: Seq[Reactor[T]] = Seq()
> }
>
> trait Reactor[-T]{
>   private var emitters: Seq[Emitter[T]] = Seq()
> }
>
> the typechecker still won't let me do it (covariant type in contravariant
> position etc.); I think it's because of the circular type-reference? I'm not
> entirely clear.
>
> I'm trying to follow Ingo Maier's implementation of Scala.React, which uses
> a mutable, dynamically generated (and regenerated) dependency tree, which is
> why I need the mutability. I'm still not entirely sure how *he* structures
> his co/contravariance and how (or even if) he solves this problem; I have
> his code working, but haven't figured it out yet.

They must be private[this] to keep things sound.

-jason

Lars Hupel | 1 Jul 2012 11:01
Picon
Favicon

Re: How to Bolster Type Parameters for Next Method Call

> case class C2[T <: X{type TT <: Y}](bs: Map[String, T])
> 
> if(/*bs are strong enough for C2*/) {
>   type TPlus = T{type TT <: Y}
>   C2((for((xi, ei) <- bs) yield (xi, ei.asInstanceOf[TPlus])).toMap[Idn, TPlus])
> }
> 
> "type arguments [TPlus] do not conform to method apply's type
> parameter bounds [T <: X{type TT <: Y}]"

Just guessing: Maybe `T` does not conform to `X`.

<insert safety advice against using `asInstanceOf` here>

Stephen Compall | 1 Jul 2012 11:22
Picon
Gravatar

Re: Why is the PECS principle not applied to Function1?

On Jun 30, 2012, at 7:31 PM, Tony Morris <tonymorris@...> wrote:
> compose/map: (A => B) => (X => A) => (X => B).

Except in Scala, the functor is the first, not second argument.  This is irrelevant for function1,
naturally, for which it is no use favoring one map/contra interpretation over the other, but matters for
the collection analogy:

F[A,B] => (X => A) => F[X,B]

--

-- 
Stephen Compall
Greetings from sunny Appleton!

Sean Parsons | 1 Jul 2012 11:33
Picon

Appears the Typesafe Repo is down.

I seem to be getting an ever hanging request if I attempt to reach this URL: http://repo.typesafe.com/typesafe/ivy-releases/ This has the nasty side effect of making SBT hang on a "Resolving X ..." step which is a little bit frustrating as it's effectively borked my use of a project if I don't go and get the jar that it's attempting to resolve manually.

Andrés Testi | 1 Jul 2012 17:14
Picon

Why the compiler allows nonsense pattern matching?

I know this should be a well known issue, but why the compiler allows nonsense pattern matching expressions like this:


val List(a, b, c): List[Int] = Some("hello") // This compiles!!!

List[Int] is not Option[String] !!!

Is it a bug or an issue related to type erasure? Will it be solved in a future release?
Regards.

- Andrés

Gmane