tagged types

450 views
Skip to first unread message

Paul Phillips

unread,
May 27, 2013, 4:47:31 PM5/27/13
to shapel...@googlegroups.com
I never heard anything, good or bad, about this:


Given all the enthusiasm lavished upon tagged types, I am surprised not to hear something. Mostly what I am interested in is whether this falls down in some way relative to whatever people are using tagged types for. One thing I know (being somewhat familiar with the compiler implementation) is that, at least at present, my approach is going to work in more contexts and with fewer crashes.

Ben Hutchison

unread,
May 27, 2013, 7:25:58 PM5/27/13
to shapel...@googlegroups.com
Hi Paul,

Well, I am probably a tagged-types "enthusiast", I did see your
earlier post to the scala list, studied the gist, and noted the
unfortunate silence that ensued.

Speaking for myself, I was not familiar enough with your proposal to
offer a sensible response/comment as yet. It's subtle stuff!
(Similarly, it took me months to get used to the Scalaz/Shapeless
-style tagged types, and after encountering multiple examples.)

Hopefully, other's grok it better than I and can offer some informed feedback..

-Ben
> --
> You received this message because you are subscribed to the Google Groups
> "Shapeless Dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to shapeless-de...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Miles Sabin

unread,
May 28, 2013, 7:24:07 AM5/28/13
to shapel...@googlegroups.com
The main use case for tagged types seems to guiding type class
resolution in cases where there are multiple alternatives.

https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/Tags.scala

and see here for the FirstOption and LastOption instances,

https://github.com/scalaz/scalaz/blob/scalaz-seven/core/src/main/scala/scalaz/std/Option.scala#L85

I think it really is the intersection type aspect of shapeless/scalaz
tagging which is doing the work here, so unfortunately your approach
which (unless I'm misreading the gist) depends in introducing
additional phantom type parameters, isn't really applicable.

Your approach works nicely for units of measure, which is great, but
that isn't something that tagging has ever been appropriate for.

I think that in general value classes replace any sane uses of
shapeless's newtype (which only partially overlaps with tagging)
construct,

https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/typeoperators.scala#L73
https://github.com/milessabin/shapeless/blob/master/examples/src/main/scala/shapeless/examples/newtype.scala

I'll most likely drop newtype at the point at which shapeless starts
requiring Scala >= 2.10.

Cheers,


Miles

--
Miles Sabin
tel: +44 7813 944 528
skype: milessabin
gtalk: mi...@milessabin.com
g+: http://www.milessabin.com
http://twitter.com/milessabin

Paul Phillips

unread,
May 31, 2013, 12:24:46 PM5/31/13
to shapel...@googlegroups.com

On Tue, May 28, 2013 at 4:24 AM, Miles Sabin <mi...@milessabin.com> wrote:
The main use case for tagged types seems to guiding type class
resolution in cases where there are multiple alternatives.

I see. Is it generally agreed upon that the available means for guiding such resolutions are ridiculously impoverished, or is that my private territory? The cognitive dissonance comes with a vengeance for me whenever I find myself going through these crazy gyrations to express something very simple like "A < B < C" , and this in a language I'm ostensibly implementing. The icing on the cake is that the extremely limited means we DO have of expressing simple linear prioritization are hopelessly entangled with unrelated concerns, often to the point of uselessness (contravariance) or activity hostility to correctness, as in this classic dance with fallbackStringCanBuildFrom:


scala> import scala.collection.immutable.Seq._
import scala.collection.immutable.Seq._

scala> (Set(1, 2, 3).map(_ * 2)(collection.breakOut)): Seq[Int]
<console>:11: error: ambiguous implicit values:
 both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String]
 and method canBuildFrom in object Seq of type [A]=> scala.collection.generic.CanBuildFrom[collection.immutable.Seq.Coll,A,scala.collection.immutable.Seq[A]]
 match expected type scala.collection.generic.CanBuildFrom[Nothing,T,To]
              (Set(1, 2, 3).map(_ * 2)(collection.breakOut)): Seq[Int]
                                                  ^

That's right scala, I would like to proceed from a Set of Ints to a Seq of Ints in any reasonably expeditious fashion. We can take the scenic route, there's no hurry. What's that you say? We can't book that trip? Because of who now?

  CanBuildFrom[String,Char,String]

Well what the ^#@#( does he have to say about it anyway? I guess some builders think everyone's business is their business.

Bryan Hunt

unread,
Jun 1, 2013, 5:47:21 PM6/1/13
to shapel...@googlegroups.com
Works on mine (Scala 2.10):

scala> (Set(1, 2, 3).map(_ * 2)(collection.breakOut)):List[Int]
res2: List[Int] = List(2, 4, 6)


scala> (Set(1, 2, 3).map(_ * 2)(collection.breakOut)):Seq[Int]
res3: Seq[Int] = Vector(2, 4, 6)

scala> (Set(1, 2, 3).map(_ * 2)(collection.breakOut)):Array[Int]
res4: Array[Int] = Array(2, 4, 6)


Paul Phillips

unread,
Jun 1, 2013, 6:45:39 PM6/1/13
to shapel...@googlegroups.com

On Sat, Jun 1, 2013 at 2:47 PM, Bryan Hunt <iris...@gmail.com> wrote:
Works on mine (Scala 2.10):

These things aren't exactly sitting targets. But I was curious when it changed, so I pinpointed the commit. Good luck reasoning this one out:



Paul Phillips

unread,
Jun 1, 2013, 6:52:13 PM6/1/13
to shapel...@googlegroups.com
Oh, ha ha, it also fails in master.

% scala3
Welcome to Scala version 2.11.0-20130527-111539-e42991f407 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_21).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scala.collection.immutable.Seq._ ; (Set(1, 2, 3).map(_ * 2)(collection.breakOut)): Seq[Int]
<console>:9: error: ambiguous implicit values:
 both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String]
 and method canBuildFrom in object Seq of type [A]=> scala.collection.generic.CanBuildFrom[collection.immutable.Seq.Coll,A,scala.collection.immutable.Seq[A]]
 match expected type scala.collection.generic.CanBuildFrom[Nothing,T,To]
        (Set(1, 2, 3).map(_ * 2)(collection.breakOut)): Seq[Int]

Now you know why things which seem like they ought not to be that hard, are.
                                            ^

scala> 
Reply all
Reply to author
Forward
0 new messages