1

I am new to both Haskell and Rust and am attempting to translate Haskell code into Rust so as to compare the features that support genericity. However, it seems I either need help with syntax or some fundamental concepts in Rust.

I have this code in Haskell:

class HasEmpty a where
    empty :: a
    isEmpty :: a -> Bool

class Hashable a where
    hash :: a -> Int

class (HasEmpty x, Hashable (Element x))
        => Hashset x where
    type Element x
    size :: x -> Int

The important part is at the bottom where we define a type class named Hashset which takes a single parameter x and sub-classes HasEmpty. The body of the type class defines an associated type, which is required to be Hashable, and an associated method size.

How can I do the same thing in Rust? Here is what I've written thus far:

trait HasEmpty {
    fn empty(&self);
    fn is_empty(&self) -> bool;
}

trait Hashable {
    fn hash(&self) -> u32;
}

trait Hashset<E>
    where E: Hashable
{
    fn size(&self) -> i32;
}

This compiles and allows me to say that the associated type E is Hashable, but how can I 'inherit' the 'trait methods' of HasEmpty by using it as a supertrait? I know this is possible by saying:

trait Hashset: HasEmpty {
    fn size(&self) -> i32;
}

but is it possible to both constrain the associated type and use a supertrait? Perhaps I am asking the wrong question.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 1
    [One question per question, please](http://meta.stackexchange.com/q/39223/281829). – Shepmaster Aug 19 '16 at 03:10
  • 1
    Your Rust definition of `empty` is more like `a -> ()` in Haskell. Better would be `fn empty() -> Self;` . – Chris Emerson Aug 19 '16 at 08:15
  • 2
    I have a feeling you're using Haskell's classes inappropriately. Type classes are not like OO classes; they're more like interfaces. Unless you have a requirement to abstract over various different implementations of `Hashset` I'd just define a plain old type: `data Hashset a = ...` – Benjamin Hodgson Aug 19 '16 at 10:42

1 Answers1

1

is it possible to both constrain the associated type and use a supertrait?

Sure, I'm not sure why you didn't just combine the two syntaxes:

trait Hashset<E>: HasEmpty
    where E: Hashable
{
    fn size(&self) -> i32;
}

However, you should know that E is not an associated type, it's just a generic type. See When is it appropriate to use an associated type versus a generic type? for more info.

An associated type would be:

trait Hashset: HasEmpty {
    type E: Hashable;
    fn size(&self) -> i32;
}
Community
  • 1
  • 1
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366