- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Optional implicit conversion.
Thu, 2012-01-19, 17:17
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
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
Thu, 2012-01-19, 17:31
#2
Re: Optional implicit conversion.
On Thu, Jan 19, 2012 at 9:17 AM, Edmondo Porcu <edmondo.porcu@gmail.com> wrote:
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.
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.
Thu, 2012-01-19, 17:41
#3
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
Thu, 2012-01-19, 17:51
#4
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
>>
>>
>>
>>
>
Thu, 2012-01-19, 17:51
#5
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>
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
>
>
>
>
Thu, 2012-01-19, 18:01
#6
Re: Optional implicit conversion.
On Thu, Jan 19, 2012 at 9:41 AM, Edmondo Porcu <edmondo.porcu@gmail.com> wrote:
exists == canConvert in my example
--
Derek Williams
I still didn't get it why you have an object with an exists method...
exists == canConvert in my example
--
Derek Williams
Thu, 2012-01-19, 18:21
#7
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
> >
> >
> >
> >
>
>
Thu, 2012-01-19, 19:01
#8
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)
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)
Thu, 2012-01-19, 19:21
#9
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:
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)
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
>
>
>
>