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

Optional implicit conversion.

9 replies
edmondo1984
Joined: 2011-09-14,
User offline. Last seen 28 weeks 3 days ago.
Dear all,
Is it possible in scala to write a code as the following?
if there is an available implicit conversion from A to B, transform A to B and put in the collection.
else do nothing.

Thank you very muchBest RegardsEdmondo



Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.
Re: Optional implicit conversion.

something around these lines

trait NoConversion {
implicit def default[ A, B ] : MaybeConversion[ A, B ] = MaybeConversion( None )
}
object MaybeConversion extends NoConversion {
implicit def exists[ A, B ]( implicit view: A => B ) : MaybeConversion[ A, B ] =
MaybeConversion( Some( view ))
}
final case class MaybeConversion[ A, B ]( option: Option[ A => B ])

def test[ A ]( a: A )( implicit c: MaybeConversion[ A, Int ]) : Option[ Int ] =
c.option.map( _( a ))

test( "1" ) // None
implicit def strToInt( s: String ) = s.toInt
test( "2" ) // Some

best, -sciss-

On 19 Jan 2012, at 16:17, Edmondo Porcu wrote:

> Dear all,
>
> Is it possible in scala to write a code as the following?
>
> if there is an available implicit conversion from A to B, transform A to B and put in the collection.
>
> else do nothing.
>
>
> Thank you very much
> Best Regards
> Edmondo
>
>
>
>

Derek Williams 3
Joined: 2011-08-12,
User offline. Last seen 42 years 45 weeks ago.
Re: Optional implicit conversion.
On Thu, Jan 19, 2012 at 9:17 AM, Edmondo Porcu <edmondo.porcu@gmail.com> wrote:
Dear all,
Is it possible in scala to write a code as the following?
if there is an available implicit conversion from A to B, transform A to B and put in the collection.
else do nothing.

Sure, you probably just need another level of implicits. Something like this (not tested):
trait Convert[A,B] { def apply(in: A, list: List[B]): List[B] }
object Convert extends ConvertLow {  implicit def canConvert[A, B](implicit f: A => B): Convert[A,B] = new Convert[A,B] {    def apply(in: A, list: List[B]): List[B] = f(in) :: list   }}
trait ConvertLow {  implicit def noConvert[A, B]: Convert[A,B] = new Convert[A,B] {    def apply(in: A, list: List[B]): List[B] = list  } }
If you request an implicit Convert, if there is also a matching implicit A => B in scope then canConvert will be used, else noConvert. At least it should.
Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Optional implicit conversion.


On Thu, Jan 19, 2012 at 5:17 PM, Edmondo Porcu <edmondo.porcu@gmail.com> wrote:
Dear all,
Is it possible in scala to write a code as the following?
if there is an available implicit conversion from A to B, transform A to B and put in the collection.

CanBuildFrom

Cheers,

 

else do nothing.

Thank you very muchBest RegardsEdmondo






--
Viktor Klang

Akka Tech LeadTypesafe - The software stack for applications that scale

Twitter: @viktorklang
Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.
Re: Optional implicit conversion.

( commentary: to make sure that `exists` has priority over `default`, the trick is to put `exists` directly into the companion object, but have `default` in a trait that the companion object mixes in; that way it gets lower priority, and scalac has no conflict deciding between the two. )

On 19 Jan 2012, at 16:25, Sciss wrote:

> something around these lines
>
> trait NoConversion {
> implicit def default[ A, B ] : MaybeConversion[ A, B ] = MaybeConversion( None )
> }
> object MaybeConversion extends NoConversion {
> implicit def exists[ A, B ]( implicit view: A => B ) : MaybeConversion[ A, B ] =
> MaybeConversion( Some( view ))
> }
> final case class MaybeConversion[ A, B ]( option: Option[ A => B ])
>
> def test[ A ]( a: A )( implicit c: MaybeConversion[ A, Int ]) : Option[ Int ] =
> c.option.map( _( a ))
>
> test( "1" ) // None
> implicit def strToInt( s: String ) = s.toInt
> test( "2" ) // Some
>
> best, -sciss-
>
>
> On 19 Jan 2012, at 16:17, Edmondo Porcu wrote:
>
>> Dear all,
>>
>> Is it possible in scala to write a code as the following?
>>
>> if there is an available implicit conversion from A to B, transform A to B and put in the collection.
>>
>> else do nothing.
>>
>>
>> Thank you very much
>> Best Regards
>> Edmondo
>>
>>
>>
>>
>

edmondo1984
Joined: 2011-09-14,
User offline. Last seen 28 weeks 3 days ago.
Re: Optional implicit conversion.
I still didn't get it why you have an object with an exists method...
Thank you for your support

2012/1/19 Sciss <contact@sciss.de>
something around these lines

trait NoConversion {
  implicit def default[ A, B ] : MaybeConversion[ A, B ] = MaybeConversion( None )
}

 
object MaybeConversion extends NoConversion {
  implicit def exists[ A, B ]( implicit view: A => B ) : MaybeConversion[ A, B ] =
     MaybeConversion( Some( view ))
}
final case class MaybeConversion[ A, B ]( option: Option[ A => B ])

def test[ A ]( a: A )( implicit c: MaybeConversion[ A, Int ]) : Option[ Int ] =
  c.option.map( _( a ))

test( "1" )   // None
implicit def strToInt( s: String ) = s.toInt
test( "2" )   // Some

best, -sciss-


On 19 Jan 2012, at 16:17, Edmondo Porcu wrote:

> Dear all,
>
> Is it possible in scala to write a code as the following?
>
> if there is an available implicit conversion from A to B, transform A to B and put in the collection.
>
> else do nothing.
>
>
> Thank you very much
> Best Regards
> Edmondo
>
>
>
>


Derek Williams 3
Joined: 2011-08-12,
User offline. Last seen 42 years 45 weeks ago.
Re: Optional implicit conversion.
On Thu, Jan 19, 2012 at 9:41 AM, Edmondo Porcu <edmondo.porcu@gmail.com> wrote:
I still didn't get it why you have an object with an exists method...

exists == canConvert in my example
--
Derek Williams
Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.
Re: Optional implicit conversion.

well, the long story...

you want to be able to call a method with an optional implicit conversion. you can translate that to calling a method with an implicit argument holding an optional conversion. i decided to use a new type `MaybeConversion` for this optional argument (you could have probably just asked for ( implicit view: Option[ A => B ]), but i think it's better to isolate things here).

so now you need to be able to call a method

def doSomething[ A, B ]( implicit optional: MaybeConversion[ A, B ])

for the two scenarios

(1) - an implicit conversion A => B exists
(2) - or it doesn't exist (what i call the 'default' case here)

scala looks in certain places to find an implicit of type MaybeConversion[ A, B ]. Among other things in the companion object of that type (so in 'object MaybeConversion'). For a full list, see this post: http://eed3si9n.com/revisiting-implicits-without-import-tax

so we must satisfy the two cases (1) and (2) for example in `object MaybeConversion`

(1) - provide a wrapper for a given implicit view A => B (this method we call `exists`)
(2) - provide the 'None' version if (1) fails (this is method `default`)

now the only thing to remember is that (2) must be lower priority than (1), so the trick is to mix it in from another trait (`NoConvesion`).

best, -sciss-

On 19 Jan 2012, at 16:41, Edmondo Porcu wrote:

> I still didn't get it why you have an object with an exists method...
>
> Thank you for your support
>
>
> 2012/1/19 Sciss
> something around these lines
>
> trait NoConversion {
> implicit def default[ A, B ] : MaybeConversion[ A, B ] = MaybeConversion( None )
> }
>
>
> object MaybeConversion extends NoConversion {
> implicit def exists[ A, B ]( implicit view: A => B ) : MaybeConversion[ A, B ] =
> MaybeConversion( Some( view ))
> }
> final case class MaybeConversion[ A, B ]( option: Option[ A => B ])
>
> def test[ A ]( a: A )( implicit c: MaybeConversion[ A, Int ]) : Option[ Int ] =
> c.option.map( _( a ))
>
> test( "1" ) // None
> implicit def strToInt( s: String ) = s.toInt
> test( "2" ) // Some
>
> best, -sciss-
>
>
> On 19 Jan 2012, at 16:17, Edmondo Porcu wrote:
>
> > Dear all,
> >
> > Is it possible in scala to write a code as the following?
> >
> > if there is an available implicit conversion from A to B, transform A to B and put in the collection.
> >
> > else do nothing.
> >
> >
> > Thank you very much
> > Best Regards
> > Edmondo
> >
> >
> >
> >
>
>

Ittay Dror 2
Joined: 2010-05-05,
User offline. Last seen 42 years 45 weeks ago.
Re: Optional implicit conversion.
Something like this?:
scala> def put[A, B, CC[B] <: TraversableOnce[B]](a: A, cc: CC[B])(implicit cbf: scala.collection.generic.CanBuildFrom[CC[B], B, CC[B]], ev: A => B): CC[B] = {val b = cbf(); b ++= cc; b += (a: B); b.result}
put: [A, B, CC[B] <: TraversableOnce[B]](a: A, cc: CC[B])(implicit cbf: scala.collection.generic.CanBuildFrom[CC[B],B,CC[B]], implicit ev: (A) => B)CC[B]

scala> put(1, List[Int]())
res32: List[Int] = List(1)
Ittay Dror 2
Joined: 2010-05-05,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Optional implicit conversion.
Sorry:
scala> def put[A, B, CC[B] <: TraversableOnce[B]](a: A, cc: CC[B])(implicit cbf: scala.collection.generic.CanBuildFrom[CC[B], B, CC[B]], ev: A => B = null): CC[B] = {val b = cbf(); b ++= cc; if (ev != null) b += (a: B); b.result}
put: [A, B, CC[B] <: TraversableOnce[B]](a: A, cc: CC[B])(implicit cbf: scala.collection.generic.CanBuildFrom[CC[B],B,CC[B]], implicit ev: (A) => B)CC[B]

scala> put(1, List[Int]())
res32: List[Int] = List(1)

Ittay Dror wrote:
Something like this?:
scala> def put[A, B, CC[B] <: TraversableOnce[B]](a: A, cc: CC[B])(implicit cbf: scala.collection.generic.CanBuildFrom[CC[B], B, CC[B]], ev: A => B): CC[B] = {val b = cbf(); b ++= cc; b += (a: B); b.result}
put: [A, B, CC[B] <: TraversableOnce[B]](a: A, cc: CC[B])(implicit cbf: scala.collection.generic.CanBuildFrom[CC[B],B,CC[B]], implicit ev: (A) => B)CC[B]

scala> put(1, List[Int]())
res32: List[Int] = List(1)

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