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

Haskell 1.0 type-classes vs. Scala implicits

19 replies
Florian Haftmann
Joined: 2010-06-14,
User offline. Last seen 32 weeks 4 days ago.

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

Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: Haskell 1.0 type-classes vs. Scala implicits

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...
>
>

adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
Re: Haskell 1.0 type-classes vs. Scala implicits
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 classeshere's what we submitted (we're currently revising it -- feedback welcome)

Type Classes as Objects and Implicits


cheers

adriaan

Mirko Stocker
Joined: 2009-09-10,
User offline. Last seen 45 weeks 6 days ago.
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

Meredith Gregory
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
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:
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 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
Bruno Oliveira 2
Joined: 2009-11-26,
User offline. Last seen 42 years 45 weeks ago.
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

Meredith Gregory
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
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:
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
adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
Re: Haskell 1.0 type-classes vs. Scala implicits
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 paper
is your encoding available somewhere? I'd love to have a look and figure out what's different
thanks!adriaan 
Meredith Gregory
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
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:
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 paper
is 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
Meredith Gregory
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
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:
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 paper
is 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
Florian Haftmann
Joined: 2010-06-14,
User offline. Last seen 32 weeks 4 days ago.
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

adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
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
Florian Haftmann
Joined: 2010-06-14,
User offline. Last seen 32 weeks 4 days ago.
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

Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
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

Florian Haftmann
Joined: 2010-06-14,
User offline. Last seen 32 weeks 4 days ago.
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

adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
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:
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

Florian Haftmann
Joined: 2010-06-14,
User offline. Last seen 32 weeks 4 days ago.
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

Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
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

adriaanm
Joined: 2010-02-08,
User offline. Last seen 31 weeks 4 days ago.
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,

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
why not make C2 implicit? 

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


Florian Haftmann
Joined: 2010-06-14,
User offline. Last seen 32 weeks 4 days ago.
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

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