Skip to content

Instantly share code, notes, and snippets.

@hyphenrf
Last active June 24, 2022 22:13
Show Gist options
  • Save hyphenrf/f1743f49590321f6701c041aafb19512 to your computer and use it in GitHub Desktop.
Save hyphenrf/f1743f49590321f6701c041aafb19512 to your computer and use it in GitHub Desktop.
/*
Today it was asked on discord whether Haskell's typeclasses and Rust's traits are equivalent.
The answer came from a Haskeller that:
> Yes, they’re along the same lines.
> Haskell’s typeclasses are more powerful than Rust’s traits though
I found that claim a little dubious so I asked them to elaborate.. How are traits less powerful?
To which a friend of mine suggested, maybe because Rust doesn't offer functional dependencies.
I didn't see why they can't be emulated with existent features. So I replied with that,
and repeated that I don't think a system is more powerful than the other,
although admitting that Haskell provides the features in a more ergonomic way.
One of the members challenged my claim:
> how would you simulate something like `class FunDep a b | a -> b, b -> a`?
So.. here's how :P
*/
trait Depends { type On; } // `A : Depends<On=B>` in Rust == `b -> a` in Haskell
trait FunDep<B : Depends<On=Self>> : Depends<On=B> { }
// instance FunDep I32 F32
impl FunDep<f32> for i32 {}
impl Depends for f32 { type On = i32; }
impl Depends for i32 { type On = f32; }
// now let's try some erroneous instances to make sure we're correct
// instance FunDep I32 F64 -- error! I32 is already used
// instance FunDep I64 F32 -- error! F32 is already used
impl Depends for f64 { type On = i32; } // ok
impl Depends for i64 { type On = f32; } // ok
/*
// error 1
impl FunDep<f64> for i32 {} // error, mismatch between f64 and f32
// this happens during typechecking the impl, resolving the `Depends for i32` impl.
impl Depends for i32 { type On = f64; } // error, conflicting implementations
*/
/*
// error 2, same idea but swapping positions of the offending type
impl FunDep<f32> for i64 {}
impl Depends for f32 { type On = i64; }
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment