- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Haskell 1.0 type-classes vs. Scala implicits
Mon, 2010-06-14, 12:36
Hi all,
I'm currently working on some kind of translator from a Haskell-like
language to Scala. The source language contains a type-class system
(not the quite rich of contemporary Haskell but the much more simple
"classical" one from Haskell 1.0), and I have to decide what to do with
type-classes on translation. What would always work is to compile them
away into dictionaries. But it would be much more appropriate to turn
them into implicit parameters -- at least it is indicated in various
Scala literature that implicits may serve as replacement for
type-classes. Although this is appealing and quite comprehensible, an
exact description of a translation from Haskell 1.0 type-classes to
Scala implicits does not seem that trivial. Does anybody know whether
this has been undertaken previously? I am confident I can cope with the
technicalities but I want to avoid duplicated work.
Thanks a lot,
Florian
Tue, 2010-06-15, 11:37
#2
Re: Haskell 1.0 type-classes vs. Scala implicits
Related Reading:this has been superseded by: Generics of a Higher Kind (OOPSLA 2008)
Towards Equal Rights for Higher Kinded Types [4]
Poor Man's Type Classes [5]we have an upcoming paper in this year's OOPSLA that gives some more details on implicits and their relation to haskell type classeshere's what we submitted (we're currently revising it -- feedback welcome)
Type Classes as Objects and Implicits
cheers
adriaan
Tue, 2010-06-15, 12:07
#3
Re: Haskell 1.0 type-classes vs. Scala implicits
Hi all
On Tuesday 15 June 2010 12:27:25 Adriaan Moors wrote:
> we have an upcoming paper in this year's OOPSLA that gives some more
> details on implicits and their relation to haskell type classes
> here's what we submitted (we're currently revising it -- feedback welcome)
I just glanced over the paper and got stuck on the table with the comparison
to C++0X. It might be better to call it "C++0X with Concepts" since concepts
have been removed from C++0X.
Cheers
Mirko
Tue, 2010-06-15, 19:27
#4
Re: Haskell 1.0 type-classes vs. Scala implicits
Dear Adriaan,
Thanks for the links? Does this paper cover functional dependencies? i saw a mention in the review of related work, but i didn't see it covered in the technical exposition. In particular, consider the following Haskell code that implements Milner's decomposition of the π-calculus, in terms of abstractions and concretions, but doesn't make a commitment to what names are. How would you use the implicits + objects encoding to transliterate it?
Best wishes,
--greg
{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}
module Core( Nominal ,Name ,Locality ,Location ,CoreProcessSyntax ,CoreAgentSyntax ,MinimalProcessSyntax ,MinimalAgentSyntax ,ReflectiveProcessSyntax-- ,make_process ) where
-- What's in a name?
class Nominal n where nominate :: i -> n i
-- newtype Name i = Nominate i deriving (Eq, Show) newtype Name i = Name i deriving (Eq, Show)
instance Nominal Name where nominate i = Name i
-- Where are we?
class Locality a where locate :: (Eq s, Nominal n) => s -> (n i) -> a s (n i) name :: (Eq s, Nominal n) => a s (n i) -> (n i)
-- data Location s n = Locate s n deriving (Eq, Show) data Location s n = Location s n deriving (Eq, Show)
instance Locality Location where locate s n = Location s n name (Location s n) = n
-- Constraints
class CoreProcessSyntax p a x | p -> a x where zero :: p sequence :: a -> x -> p compose :: [p] -> p
class CoreAgentSyntax x p n | x -> p n where bind :: [n] -> p -> x offer :: [n] -> p -> x
-- Freedom (as in freely generated)
data MinimalProcessSyntax l x = Null | Sequence l x | Composition [MinimalProcessSyntax l x]
data MinimalAgentSyntax n p = Thunk (() -> p) | Abstraction ([n] -> p) | Concretion [n] p
-- Responsibility : constraining freedom to enjoy order
instance CoreProcessSyntax (MinimalProcessSyntax l x) l x where zero = Null sequence l a = Sequence l a compose [] = zero compose ps = Composition ps
instance CoreAgentSyntax (MinimalAgentSyntax n p) p n where bind [] proc = Thunk (\() -> proc)-- -- TODO : lgm : need to substitute m for name in proc bind (name:names) proc = Abstraction (\m -> comp $ bind names proc) where comp (Thunk fp) = fp () -- comp (Abstraction abs) = abs name offer names proc = Concretion names proc
data ReflectiveProcessSyntax = Reflect (MinimalProcessSyntax (Location [(Name ReflectiveProcessSyntax)] (Name ReflectiveProcessSyntax)) (MinimalAgentSyntax (Name ReflectiveProcessSyntax) ReflectiveProcessSyntax))
-- instance (CoreProcessSyntax p a x) =>-- CoreProcessSyntax -- (MinimalProcessSyntax-- (Location -- [(Name (MinimalProcessSyntax a x))]-- (Name (MinimalProcessSyntax a x))) -- (MinimalAgentSyntax-- (Name (MinimalProcessSyntax a x)) -- (MinimalProcessSyntax a x)))-- (Location -- [(Name (MinimalProcessSyntax a x))]-- (Name (MinimalProcessSyntax a x))) -- (MinimalAgentSyntax-- (Name (MinimalProcessSyntax a x)) -- (MinimalProcessSyntax a x))
On Tue, Jun 15, 2010 at 3:27 AM, Adriaan Moors <adriaan [dot] moors [at] epfl [dot] ch> wrote:
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
Thanks for the links? Does this paper cover functional dependencies? i saw a mention in the review of related work, but i didn't see it covered in the technical exposition. In particular, consider the following Haskell code that implements Milner's decomposition of the π-calculus, in terms of abstractions and concretions, but doesn't make a commitment to what names are. How would you use the implicits + objects encoding to transliterate it?
Best wishes,
--greg
{-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}
module Core( Nominal ,Name ,Locality ,Location ,CoreProcessSyntax ,CoreAgentSyntax ,MinimalProcessSyntax ,MinimalAgentSyntax ,ReflectiveProcessSyntax-- ,make_process ) where
-- What's in a name?
class Nominal n where nominate :: i -> n i
-- newtype Name i = Nominate i deriving (Eq, Show) newtype Name i = Name i deriving (Eq, Show)
instance Nominal Name where nominate i = Name i
-- Where are we?
class Locality a where locate :: (Eq s, Nominal n) => s -> (n i) -> a s (n i) name :: (Eq s, Nominal n) => a s (n i) -> (n i)
-- data Location s n = Locate s n deriving (Eq, Show) data Location s n = Location s n deriving (Eq, Show)
instance Locality Location where locate s n = Location s n name (Location s n) = n
-- Constraints
class CoreProcessSyntax p a x | p -> a x where zero :: p sequence :: a -> x -> p compose :: [p] -> p
class CoreAgentSyntax x p n | x -> p n where bind :: [n] -> p -> x offer :: [n] -> p -> x
-- Freedom (as in freely generated)
data MinimalProcessSyntax l x = Null | Sequence l x | Composition [MinimalProcessSyntax l x]
data MinimalAgentSyntax n p = Thunk (() -> p) | Abstraction ([n] -> p) | Concretion [n] p
-- Responsibility : constraining freedom to enjoy order
instance CoreProcessSyntax (MinimalProcessSyntax l x) l x where zero = Null sequence l a = Sequence l a compose [] = zero compose ps = Composition ps
instance CoreAgentSyntax (MinimalAgentSyntax n p) p n where bind [] proc = Thunk (\() -> proc)-- -- TODO : lgm : need to substitute m for name in proc bind (name:names) proc = Abstraction (\m -> comp $ bind names proc) where comp (Thunk fp) = fp () -- comp (Abstraction abs) = abs name offer names proc = Concretion names proc
data ReflectiveProcessSyntax = Reflect (MinimalProcessSyntax (Location [(Name ReflectiveProcessSyntax)] (Name ReflectiveProcessSyntax)) (MinimalAgentSyntax (Name ReflectiveProcessSyntax) ReflectiveProcessSyntax))
-- instance (CoreProcessSyntax p a x) =>-- CoreProcessSyntax -- (MinimalProcessSyntax-- (Location -- [(Name (MinimalProcessSyntax a x))]-- (Name (MinimalProcessSyntax a x))) -- (MinimalAgentSyntax-- (Name (MinimalProcessSyntax a x)) -- (MinimalProcessSyntax a x)))-- (Location -- [(Name (MinimalProcessSyntax a x))]-- (Name (MinimalProcessSyntax a x))) -- (MinimalAgentSyntax-- (Name (MinimalProcessSyntax a x)) -- (MinimalProcessSyntax a x))
On Tue, Jun 15, 2010 at 3:27 AM, Adriaan Moors <adriaan [dot] moors [at] epfl [dot] ch> wrote:
Related Reading:this has been superseded by: Generics of a Higher Kind (OOPSLA 2008)
Towards Equal Rights for Higher Kinded Types [4]
Poor Man's Type Classes [5]we have an upcoming paper in this year's OOPSLA that gives some more details on implicits and their relation to haskell type classeshere's what we submitted (we're currently revising it -- feedback welcome)Type Classes as Objects and Implicits
cheers
adriaan
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
Wed, 2010-06-16, 05:37
#5
Re: Haskell 1.0 type-classes vs. Scala implicits
Dear Meredith,
As you mention, the paper does not cover functional dependencies.
However, for you particular example, you should be able to use
associated types instead of functional dependencies. Something like:
> class CoreAgentSyntax x where
> type P x
> type N x
> bind :: [N x] -> P x -> x
> offer :: [N x] -> P x -> x
and then you can try to encode this in Scala.
Unfortunately, I believe that there are still some bugs in the compiler,
which may prevent you from progressing. Adriaan is working
hard trying to fix those, but I believe that they are
not yet available in the main distribution.
All the best,
Bruno
On Tue, 2010-06-15 at 11:12 -0700, Meredith Gregory wrote:
> Dear Adriaan,
>
>
> Thanks for the links? Does this paper cover functional dependencies? i
> saw a mention in the review of related work, but i didn't see it
> covered in the technical exposition. In particular, consider the
> following Haskell code that implements Milner's decomposition of the
> π-calculus, in terms of abstractions and concretions, but doesn't make
> a commitment to what names are. How would you use the implicits +
> objects encoding to transliterate it?
>
>
> Best wishes,
>
>
> --greg
>
>
> {-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}
>
>
> module Core(
> Nominal
> ,Name
> ,Locality
> ,Location
> ,CoreProcessSyntax
> ,CoreAgentSyntax
> ,MinimalProcessSyntax
> ,MinimalAgentSyntax
> ,ReflectiveProcessSyntax
Wed, 2010-06-16, 07:07
#6
Re: Haskell 1.0 type-classes vs. Scala implicits
Dear Bruno,
Thanks for your reply! Actually, i have a direct encoding of this code in Scala code. However, my encoding is slightly different than the one suggested by the treatment of type classes in the draft paper you and Adriaan are writing. So, i was wondering if your approach would generate different code -- that way i could compare and see what the trade-offs were in each treatment of type classes.
Best wishes,
--greg
On Tue, Jun 15, 2010 at 9:29 PM, Bruno Oliveira <bruno [at] ropas [dot] snu [dot] ac [dot] kr> wrote:
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
Thanks for your reply! Actually, i have a direct encoding of this code in Scala code. However, my encoding is slightly different than the one suggested by the treatment of type classes in the draft paper you and Adriaan are writing. So, i was wondering if your approach would generate different code -- that way i could compare and see what the trade-offs were in each treatment of type classes.
Best wishes,
--greg
On Tue, Jun 15, 2010 at 9:29 PM, Bruno Oliveira <bruno [at] ropas [dot] snu [dot] ac [dot] kr> wrote:
Dear Meredith,
As you mention, the paper does not cover functional dependencies.
However, for you particular example, you should be able to use
associated types instead of functional dependencies. Something like:
> class CoreAgentSyntax x where
> type P x
> type N x
> bind :: [N x] -> P x -> x
> offer :: [N x] -> P x -> x
and then you can try to encode this in Scala.
Unfortunately, I believe that there are still some bugs in the compiler,
which may prevent you from progressing. Adriaan is working
hard trying to fix those, but I believe that they are
not yet available in the main distribution.
All the best,
Bruno
On Tue, 2010-06-15 at 11:12 -0700, Meredith Gregory wrote:
> Dear Adriaan,
>
>
> Thanks for the links? Does this paper cover functional dependencies? i
> saw a mention in the review of related work, but i didn't see it
> covered in the technical exposition. In particular, consider the
> following Haskell code that implements Milner's decomposition of the
> π-calculus, in terms of abstractions and concretions, but doesn't make
> a commitment to what names are. How would you use the implicits +
> objects encoding to transliterate it?
>
>
> Best wishes,
>
>
> --greg
>
>
> {-# OPTIONS -fglasgow-exts -fallow-undecidable-instances #-}
>
>
> module Core(
> Nominal
> ,Name
> ,Locality
> ,Location
> ,CoreProcessSyntax
> ,CoreAgentSyntax
> ,MinimalProcessSyntax
> ,MinimalAgentSyntax
> ,ReflectiveProcessSyntax
> -- ,make_process
> )
> where
>
>
> -- What's in a name?
>
>
> class Nominal n where
> nominate :: i -> n i
>
>
> -- newtype Name i = Nominate i deriving (Eq, Show)
> newtype Name i = Name i deriving (Eq, Show)
>
>
> instance Nominal Name where nominate i = Name i
>
>
> -- Where are we?
>
>
> class Locality a where
> locate :: (Eq s, Nominal n) => s -> (n i) -> a s (n i)
> name :: (Eq s, Nominal n) => a s (n i) -> (n i)
>
>
> -- data Location s n = Locate s n deriving (Eq, Show)
> data Location s n = Location s n deriving (Eq, Show)
>
>
> instance Locality Location where
> locate s n = Location s n
> name (Location s n) = n
>
>
>
>
> -- Constraints
>
>
> class CoreProcessSyntax p a x | p -> a x where
> zero :: p
> sequence :: a -> x -> p
> compose :: [p] -> p
>
>
> class CoreAgentSyntax x p n | x -> p n where
> bind :: [n] -> p -> x
> offer :: [n] -> p -> x
>
>
> -- Freedom (as in freely generated)
>
>
> data MinimalProcessSyntax l x =
> Null
> | Sequence l x
> | Composition [MinimalProcessSyntax l x]
>
>
> data MinimalAgentSyntax n p =
> Thunk (() -> p)
> | Abstraction ([n] -> p)
> | Concretion [n] p
>
>
> -- Responsibility : constraining freedom to enjoy order
>
>
> instance CoreProcessSyntax (MinimalProcessSyntax l x) l x where
> zero = Null
> sequence l a = Sequence l a
> compose [] = zero
> compose ps = Composition ps
>
>
> instance CoreAgentSyntax (MinimalAgentSyntax n p) p n where
> bind [] proc = Thunk (\() -> proc)
> -- -- TODO : lgm : need to substitute m for name in proc
> bind (name:names) proc = Abstraction (\m -> comp $ bind names
> proc)
> where comp (Thunk fp) = fp ()
> -- comp (Abstraction abs) = abs name
> offer names proc = Concretion names proc
>
>
> data ReflectiveProcessSyntax =
> Reflect
> (MinimalProcessSyntax
> (Location [(Name ReflectiveProcessSyntax)] (Name
> ReflectiveProcessSyntax))
> (MinimalAgentSyntax (Name ReflectiveProcessSyntax)
> ReflectiveProcessSyntax))
>
>
> -- instance (CoreProcessSyntax p a x) =>
> -- CoreProcessSyntax
> -- (MinimalProcessSyntax
> -- (Location
> -- [(Name (MinimalProcessSyntax a x))]
> -- (Name (MinimalProcessSyntax a x)))
> -- (MinimalAgentSyntax
> -- (Name (MinimalProcessSyntax a x))
> -- (MinimalProcessSyntax a x)))
> -- (Location
> -- [(Name (MinimalProcessSyntax a x))]
> -- (Name (MinimalProcessSyntax a x)))
> -- (MinimalAgentSyntax
> -- (Name (MinimalProcessSyntax a x))
> -- (MinimalProcessSyntax a x))
>
> On Tue, Jun 15, 2010 at 3:27 AM, Adriaan Moors <adriaan [dot] moors [at] epfl [dot] ch>
> wrote:
> Related Reading:
>
> Towards Equal Rights for Higher Kinded Types [4]
> this has been superseded by: Generics of a Higher Kind (OOPSLA
> 2008)
>
>
>
> Poor Man's Type Classes [5]
> we have an upcoming paper in this year's OOPSLA that gives
> some more details on implicits and their relation to haskell
> type classes
> here's what we submitted (we're currently revising it --
> feedback welcome)
> Type Classes as Objects and Implicits
>
>
> cheers
> adriaan
>
>
>
> --
> L.G. Meredith
> Managing Partner
> Biosimilarity LLC
> 1219 NW 83rd St
> Seattle, WA 98117
>
> +1 206.650.3740
>
> http://biosimilarity.blogspot.com
>
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
Wed, 2010-06-16, 08:47
#7
Re: Haskell 1.0 type-classes vs. Scala implicits
Hi Greg,
2010/6/16 Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com>
thanks!adriaan
2010/6/16 Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com>
Actually, i have a direct encoding of this code in Scala code. However, my encoding is slightly different than the one suggested by the treatment of type classes in the draft paperis your encoding available somewhere? I'd love to have a look and figure out what's different
thanks!adriaan
Wed, 2010-06-16, 22:07
#8
Re: Haskell 1.0 type-classes vs. Scala implicits
Dear Adriaan,
i posted it to the list some time back, but i'll dig it up and send it along. It'll have to be later today or tomorrow.
Best wishes,
--greg
On Wed, Jun 16, 2010 at 12:39 AM, Adriaan Moors <adriaan [dot] moors [at] epfl [dot] ch> wrote:
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
i posted it to the list some time back, but i'll dig it up and send it along. It'll have to be later today or tomorrow.
Best wishes,
--greg
On Wed, Jun 16, 2010 at 12:39 AM, Adriaan Moors <adriaan [dot] moors [at] epfl [dot] ch> wrote:
Hi Greg,
2010/6/16 Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com>Actually, i have a direct encoding of this code in Scala code. However, my encoding is slightly different than the one suggested by the treatment of type classes in the draft paperis your encoding available somewhere? I'd love to have a look and figure out what's different
thanks!adriaan
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
Thu, 2010-06-17, 01:57
#9
Re: Haskell 1.0 type-classes vs. Scala implicits
Dear Adriaan,
This code was written for Scala 2.7.x. No guarantees that it still works.
Best wishes,
--greg
On Wed, Jun 16, 2010 at 1:51 PM, Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com> wrote:
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
This code was written for Scala 2.7.x. No guarantees that it still works.
Best wishes,
--greg
On Wed, Jun 16, 2010 at 1:51 PM, Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com> wrote:
Dear Adriaan,
i posted it to the list some time back, but i'll dig it up and send it along. It'll have to be later today or tomorrow.
Best wishes,
--greg
On Wed, Jun 16, 2010 at 12:39 AM, Adriaan Moors <adriaan [dot] moors [at] epfl [dot] ch> wrote:
Hi Greg,
2010/6/16 Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com>Actually, i have a direct encoding of this code in Scala code. However, my encoding is slightly different than the one suggested by the treatment of type classes in the draft paperis your encoding available somewhere? I'd love to have a look and figure out what's different
thanks!adriaan
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
Thu, 2010-06-17, 08:47
#10
Re: Haskell 1.0 type-classes vs. Scala implicits
Hi Adriaan et al,
thanks for the answers.
I have studied the paper draft and it is reassuring that my thoughts in
large parts coincide with the proposal developed there ;-)
The context bound syntax (p5, sect 3.3)
def f[T: Ord](...): ...
is a great idea! But I wonder how this syntax covers the case where one
type variable is an instance of multiple classes, e.g. how would the
Haskell snippet
foo :: (Eq a, Show a) => a -> Bool
foo x = show x == "foo"
translate to Scala context bounds?
My primary concern with the translation has to do with subclassing. The
example in Figure 3 (p7) is not the real thing because here subclassing
is a real specialization in the sense that the operations of the
superclasses can be expressed in terms of operations of the class
itself. In general, this is not the case, e.g. in a hierarchy
semigroup (def *) -> monoid (def one) -> group (def inverse)
each operation is to be defined seperately.
I want to use the implicits approach to implement type classes, since
this is the most idiomatic thing. One could think that also subclassing
can be implemented using implicits converting from a class to one of its
superclasses, but this does not work since the type class hierarchy
contains diamonds; given
c -> d, c -> e, d -> f, e -> f
two paths allow to get from f to c:
c -> d -> f
c -> e -> f
Although the choice is irrelevant, the compiler will complain here.
Hence superclassing is must be implemented using subtyping. This has
the consequence that in the definition of an instance
def C_T[A: ..., B: ...] = new C[T[A, B]] {
...
}
the body "..." must contain the union of all superclasses. I do not
consider this as a desaster, but I asked myself the question whether
anybody out there has already made up a solution which can avoid this.
But it is not mission-critical.
Regards,
Florian
Thu, 2010-06-17, 09:07
#11
Re: Haskell 1.0 type-classes vs. Scala implicits
On Thu, Jun 17, 2010 at 9:44 AM, Florian Haftmann <florian [dot] haftmann [at] informatik [dot] tu-muenchen [dot] de> wrote:
Hence superclassing is must be implemented using subtyping.typically it would be implemented using delegation -- we should explain this better
class Super[T] // class Superclass Sub[T] // class Super => Subimplicit def mkDictSubInt(implicit supr: Super[Int]): Sub[Int] // instance Sub Int
ah, and I think the encoding of multiple context bounds (another good question!) is possible using tupling and an implicit that will collect different instances into a tuple (untested):
trait Gimme[A[_], B[_]] { type Both[T] = (A[T], B[T])}implicit def both[A, B](implicit a: A, b: B): (A, B) = (a, b)
def f[T: Gimme[Eq, Show]#Both]
cheersadriaan
Thu, 2010-06-17, 09:27
#12
Re: Haskell 1.0 type-classes vs. Scala implicits
Hi Adriaan,
> ah, and I think the encoding of multiple context bounds (another good
> question!) is possible using tupling and an implicit that will collect
> different instances into a tuple (untested):
>
> trait Gimme[A[_], B[_]] {
> type Both[T] = (A[T], B[T])
> }
> implicit def both[A, B](implicit a: A, b: B): (A, B) = (a, b)
>
> def f[T: Gimme[Eq, Show]#Both]
my suggestion would be: since context bounds are an extension anyway, it
should be possible to extend the syntax in a suitable manner (perhaps
just "T: (A, B)"?).
> typically it would be implemented using delegation -- we should explain
> this better
>
> class Super[T] // class Super
> class Sub[T] // class Super => Sub
> implicit def mkDictSubInt(implicit supr: Super[Int]): Sub[Int] // instance Sub Int
Ok, you propose to have the superclass projections on the instance level
C[Int] rather than the class level C[A]. But I don't see whether this
would resolve the diamond issue -- given the hierarchy Super -> C, Super
-> D, C -> Sub, D -> Sub, there would still be ambiguity:
Super[Int] -> C[Int] -> Sub[Int]
Super[Int] -> D[Int] -> Sub[Int]
Of course a solution could be to spell out the transitive superclass
projections explicitly, e.g. in this examples there would be implicits for
C[Int] -> Super[Int]
D[Int] -> Super[Int]
Sub[Int] -> C[Int]
Sub[Int] -> D[Int]
Sub[Int] -> Super[Int]
making the step from Sub to Super unique. (I believe this would also
work on the abstract level, replacing Int by A). This would mean that
we spell out the class hierarchy in full detail rather than the class
method instance hierarchy, which is perhaps preferable.
Regards,
Florian
Thu, 2010-06-17, 09:27
#13
Re: Haskell 1.0 type-classes vs. Scala implicits
How is this different from the following?
def f[T: Eq : Show] = //...
-jason
On Thu, Jun 17, 2010 at 9:58 AM, Adriaan Moors wrote:
> ah, and I think the encoding of multiple context bounds (another good
> question!) is possible using tupling and an implicit that will collect
> different instances into a tuple (untested):
> trait Gimme[A[_], B[_]] {
> type Both[T] = (A[T], B[T])
> }
> implicit def both[A, B](implicit a: A, b: B): (A, B) = (a, b)
> def f[T: Gimme[Eq, Show]#Both]
> cheers
> adriaan
Thu, 2010-06-17, 09:37
#14
Re: Haskell 1.0 type-classes vs. Scala implicits
Am 17.06.2010 10:16, schrieb Jason Zaugg:
> How is this different from the following?
>
> def f[T: Eq : Show] = //...
Ok, the syntax is already there.
Florian
Thu, 2010-06-17, 09:47
#15
Re: Haskell 1.0 type-classes vs. Scala implicits
whoops -- I should have checked :-)
thanks Jason!a
On Thu, Jun 17, 2010 at 10:16 AM, Jason Zaugg <jzaugg [at] gmail [dot] com> wrote:
thanks Jason!a
On Thu, Jun 17, 2010 at 10:16 AM, Jason Zaugg <jzaugg [at] gmail [dot] com> wrote:
How is this different from the following?
def f[T: Eq : Show] = //...
-jason
On Thu, Jun 17, 2010 at 9:58 AM, Adriaan Moors <adriaan [dot] moors [at] epfl [dot] ch> wrote:
> ah, and I think the encoding of multiple context bounds (another good
> question!) is possible using tupling and an implicit that will collect
> different instances into a tuple (untested):
> trait Gimme[A[_], B[_]] {
> type Both[T] = (A[T], B[T])
> }
> implicit def both[A, B](implicit a: A, b: B): (A, B) = (a, b)
> def f[T: Gimme[Eq, Show]#Both]
> cheers
> adriaan
Thu, 2010-06-17, 10:38
#16
Re: Haskell 1.0 type-classes vs. Scala implicits
Hi again,
the proposal with implicit conversions between type classes does also
not work:
trait C1[A] {
def f: A
}
def f[A](implicit C1: C1[A]): A = C1.f;
trait C2[A] {
val C1: C1[A]
def f2: A
}
implicit def C1_C2[A](C2: C2[A]): C1[A] = C2.C1
def g[A: C1]: A = f
def h[A: C2]: A = g
In h, on the right hand side there is a problem: what should be inserted
is C1_C2(C2), but Scala will only insert coercions for explicit arguments.
Perhaps the best thing is really to stick with instances which spell out
the whole hierarchy of super instances.
Regards,
Florian
Thu, 2010-06-17, 10:47
#17
Re: Haskell 1.0 type-classes vs. Scala implicits
But hey, it's fun inventing types to use context bounds in weird and
wonderful ways, for example you can express a view bound:
http://stackoverflow.com/questions/2982276/what-is-a-context-bound-in-sc...
-jason
On Thu, Jun 17, 2010 at 10:32 AM, Adriaan Moors wrote:
> whoops -- I should have checked :-)
> thanks Jason!
> a
>
> On Thu, Jun 17, 2010 at 10:16 AM, Jason Zaugg wrote:
>>
>> How is this different from the following?
>>
>> def f[T: Eq : Show] = //...
>>
>> -jason
Thu, 2010-06-17, 10:57
#18
Re: Haskell 1.0 type-classes vs. Scala implicits
On Thu, Jun 17, 2010 at 11:28 AM, Florian Haftmann <florian [dot] haftmann [at] informatik [dot] tu-muenchen [dot] de> wrote:
Hi again,why not make C2 implicit?
the proposal with implicit conversions between type classes does also
not work:
trait C1[A] {
def f: A
}
def f[A](implicit C1: C1[A]): A = C1.f;
trait C2[A] {
val C1: C1[A]
def f2: A
}
implicit def C1_C2[A](C2: C2[A]): C1[A] = C2.C1
def g[A: C1]: A = f
def h[A: C2]: A = g
In h, on the right hand side there is a problem: what should be inserted
is C1_C2(C2), but Scala will only insert coercions for explicit arguments.
Perhaps the best thing is really to stick with instances which spell out
the whole hierarchy of super instances.
Regards,
Florian
--
Home:
http://www.in.tum.de/~haftmann
PGP available:
http://home.informatik.tu-muenchen.de/haftmann/pgp/florian_haftmann_at_informatik_tu_muenchen_de
Thu, 2010-06-17, 11:07
#19
Re: Haskell 1.0 type-classes vs. Scala implicits
> why not make C2 implicit?
yes, would be a good idea ;-)
But then the story is still not done:
object Misc {
trait C1[A] {
def f: A
}
def f[A](implicit C1: C1[A]): A = C1.f;
trait C2[A] {
val C1: C1[A]
}
implicit def C1_C2[A](implicit C2: C2[A]): C1[A] = C2.C1
trait C3[A] {
val C1: C1[A]
}
implicit def C1_C3[A](implicit C3: C3[A]): C1[A] = C3.C1
trait C4[A] {
val C2: C2[A]
val C3: C3[A]
}
implicit def C2_C4[A](implicit C4: C4[A]): C2[A] = C4.C2
implicit def C3_C4[A](implicit C4: C4[A]): C3[A] = C4.C3
implicit def C1_C4[A](implicit C4: C4[A]): C1[A] = C4.C2.C1
def g[A: C1]: A = f
def h[A: C2]: A = g
def k[A: C3]: A = g
def l[A: C4]: A = g
}
Here Scala claims an ambiguity for the right hand side of l:
> error: ambiguous implicit values:
> both method C1_C4 in object Misc of type [A](implicit C4: Misc.C4[A])Misc.C1[A]
> and method C1_C3 in object Misc of type [A](implicit C3: Misc.C3[A])Misc.C1[A]
> match expected type Misc.C1[A]
> def l[A: C4]: A = g
The original though was that C1_C4 is specific enough to render this
ambiguity irrelevant, but this seems to be a fault.
Regards,
Florian
Scalaz [1] encodes a broad selection of type classes with implicit
parameters. Take a look at Functor [2], and then at Monad [3].
Simple type constructors, such as List can now be inferred, but
partially applied type constructors cannot be inferred. Furthermore,
they can't be directly expressed, you need to use type aliases (type
EitherIntA[A] = Either[Int, A]). In Scalaz, you'll see these expressed
like PartialApplyNofM[...]#Apply
Becuase of simple type constructor inference, we don't need to define
the Monad instance for List, Set, Option, as they are automatically
defined by the presence of Bind and Functor instances which are
required by the implicit function Monad.monad.
You can also use context bounds as a syntactic sugar for the implicit
parameters.
Our experience is that having covariant or contravariant type classes
tends to lead to awkward problems with type inference, and we've been
steadily been making the type classes invariant.
We provide access points to necessary implicit conversions and many
general purpose functions based on these type classes in Scalaz,
Identity and MA.
-jason
Related Reading:
Towards Equal Rights for Higher Kinded Types [4]
Poor Man's Type Classes [5]
-jason
[1] http://github.com/scalaz/scalaz
[2] http://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/F...
[3] http://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/M...
[4] www.cs.kuleuven.be/~adriaan/files/higher.pdf
[5] lampwww.epfl.ch/~odersky/talks/wg2.8-boston06.pdf
On Mon, Jun 14, 2010 at 1:35 PM, Florian Haftmann
wrote:
> Hi all,
>
> I'm currently working on some kind of translator from a Haskell-like
> language to Scala. The source language contains a type-class system
> (not the quite rich of contemporary Haskell but the much more simple
> "classical" one from Haskell 1.0), and I have to decide what to do with
> type-classes on translation. What would always work is to compile them
> away into dictionaries. But it would be much more appropriate to turn
> them into implicit parameters -- at least it is indicated in various
> Scala literature that implicits may serve as replacement for
> type-classes. Although this is appealing and quite comprehensible, an
> exact description of a translation from Haskell 1.0 type-classes to
> Scala implicits does not seem that trivial. Does anybody know whether
> this has been undertaken previously? I am confident I can cope with the
> technicalities but I want to avoid duplicated work.
>
> Thanks a lot,
> Florian
>
> --
>
> Home:
> http://www.in.tum.de/~haftmann
>
> PGP available:
> http://home.informatik.tu-muenchen.de/haftmann/pgp/florian_haftmann_at_i...
>
>