This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Abstract over Companion objects

3 replies
Sadek Drobi
Joined: 2010-09-22,
User offline. Last seen 42 years 45 weeks ago.
Hello everyone,
I was wondering if someone could help me on this. I would like to abstract over companion objects, structural types don't work because of erasure:
def a2[A1,A2,R](companion : {def apply(a1:A1, a2:A2): R ; def unapply(R):(A1,A2) }) = companion
I hoped to find a common interface on companions but that's not the case either.

Is there any other way to do the trick?
ThanksSadek
--
www.sadekdrobi.com
ʎdoɹʇuǝ
Peter 2
Joined: 2011-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Abstract over Companion objects

If you want to abstract over your own companion objects, define trait
MyCompanion[...]{ def apply...} end let your companion objects extend
this trait. Or do you have something else in mind?

Luc Duponcheel
Joined: 2008-12-19,
User offline. Last seen 34 weeks 3 days ago.
Re: Abstract over Companion objects
Sadek, in sometimes I find it more convenient not to work with companion objectsbut with nested traits instead (the outer trait, eventually, becomes an object and theinner one, eventually, becomes a case class (so I do not need companion object (un)apply features) I use the companion object for bundling implicit objects(although not strictly necessary (they could be bundled elsewhere)) this approach (together with self types) seems to be especially convenient when dealing with type parameters and variance ... at the risk of abusing the word, I would almost call it a pattern ... psI do not claim that the same thing cannot, somehow, be achieved with companion abstractions I only claim that I was not clever enough to find out how to achieve it :-)  here is some code from one of my blogs  
package com.imaginej package computationtrait ComputationModule { // begin outer trait
 type M[+Z] <: Computation[Z]
 type In[-Z]
 type Out[+Z]
 trait Computation[+A] { self: M[A] => // begin inner trait
  def run[B >: A](i: In[B]): Out[B]
 } // end   inner trait
} // end   outer trait 
package com.imaginej package monadimport computation.ComputationModuletrait MonadModule
 extends ComputationModule { // begin outer trait
 type M[+Z] <: Monad[Z]
 def _return[Z]: Z => M[Z]
 def _join[Z]: M[M[Z]] => M[Z] =
  _.flatMap(identity)
 trait Monad[+A]
  extends Computation[A] { self: M[A] => // begin inner trait
  def flatMap[B](a_f_mb: A => M[B]): M[B]
  def >=[B](a_f_mb: A => M[B]): M[B] =
   flatMap(a_f_mb)
  def >>[B](mb: => M[B]): M[B] =
   this flatMap { _ => mb }
  def map[B](afb: A => B) =
   this flatMap (afb andThen _return)
 } // end    inner trait
} // end   outer trait

package com.imaginejpackage monadpackage instances import monad.MonadModuleobject IdentityMonadObject // begin outer object
 extends MonadModule {
 type M[+Z] = IdentityMonad[Z]
 type In[-Z] = Unit
 type Out[+Z] = Z
 override def _return[Z] =
  IdentityMonad[Z](_)
 def _close[Z]: Z => M[Z] =
  IdentityMonad[Z](_)
 case class IdentityMonad[+A](val open: A)
  extends Monad[A] { // begin inner case class
  override def run[B >: A](u: Unit): B =
   this.open
  override def flatMap[B](a_f_mb: A => M[B]) =
   a_f_mb(this.open)
 } // end   inner case class
} // end  outer object

import instances.IdentityMonadObject
import instances.TraversableMonadObject
import instances.OptionMonadObject object MonadModule { // begin implicits
 implicit val identityMonad =
  IdentityMonadObject
 // other monads } // end   implicits


Luc
  On Sat, Jun 25, 2011 at 12:25 AM, Sadek Drobi <sadek [dot] drobi [at] gmail [dot] com> wrote:
Hello everyone,
I was wondering if someone could help me on this. I would like to abstract over companion objects, structural types don't work because of erasure:
def a2[A1,A2,R](companion : {def apply(a1:A1, a2:A2): R ; def unapply(R):(A1,A2) }) = companion
I hoped to find a common interface on companions but that's not the case either.

Is there any other way to do the trick?
ThanksSadek
--
www.sadekdrobi.com
ʎdoɹʇuǝ



--
   __~O
  -\ <,
(*)/ (*)

reality goes far beyond imagination

Peter 2
Joined: 2011-02-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Abstract over Companion objects

If you want to abstract over arbitrary AnyRefs and find out which
method signatures they adhere to, we could distinguish between
a) the value extends a known template => you can match it against that
template
and
b) the value has a method signature of interest without extending
anything usable for your test => no chance but reflection, afaik...

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland