6 ms·
Nice article! This Haskell is incorrect, though: {- Haskell -} type Maybe a = None | Just a {- x : Maybe t -} case x of N
by thinkpad20 12y ago
Nice article! This Haskell is incorrect, though:
{- Haskell -}
type Maybe a =
None
| Just a
{- x : Maybe t -}
case x of
None -> False
Some _ -> True
In that snippet, `type` needs to be `data`. Also the canonical constructors are `Nothing` and `Just` (but that doesn't have to do with correctness :))
There are also a few times where you use a single colon for a type annotation in Haskell, instead of a double colon.
Also, I disagree with this:
> Rust's “traits” are analogous to Haskell's type classes.
> The main difference with Haskell is that traits only intervene for expressions with dot notation, ie. of the form a.foo(b).
That's more of a syntactic distinction; the difference at a semantic level is much bigger: Haskell type classes extend to higher-order types. For example, Functor and Monad rely on a type with kind `* -> *`, and it can get more complex than that, for example with monad transformer classes (like State and Error).
Also, an important difference is that Rust traits can be used as Java-style interfaces; for example, you can have a list of objects of different types, but that all implement `Show`.
- Argorak 12y ago> Also, an important difference is that Rust traits can be used as Java-style interfaces; for example, you can have a list of objects of different types, but that all implement `Show`. To be a tiny bit nitpicky here: you can have a list of pointers to objects of different types. Vec<Show> is illegal, Vec<&Show> is not. Still, it's like Java in that regard ;).
- dbaupp 12y agoRust traits only don't support higher order types because they are missing from the whole language, i.e. it's not a philosophical difference between traits and type classes. Also, Haskell has existential types, which are exactly like Rust's trait objects.
- thinkpad20 12y agoRust has generics, which are higher order types (you can't have just a vector, it needs to be a vector "of something"). I'm not sure if the rust team would describe them that way, but there doesn't seem to be that much of a theoretical difference. Thus if they wanted to, they could (presumably) allow for a higher-order trait like Functor: trait Functor { fn map<a, b> : (|a| -> b) -> Self<a> -> Self<b> } (I'm not sure if that's valid syntax but you get the idea). As for existential types, they're an area of Haskell I haven't really explored that much, but they seem to be seen as a bit more of an advanced feature than their equivalents in Rust or Java. Not just because they require a GHC extension and additional keywords, but because there's a bit more theoretical overhead to understand how they work, while the presentation in Rust/Java is more intuitive and straightforward.
- dbaupp 12y ago> Rust has generics, which are higher order types (you can't have just a vector, it needs to be a vector "of something"). I'm not sure if the rust team would describe them that way, but there doesn't seem to be that much of a theoretical difference. No, there's no first class "type level functions", i.e. you always need `Vec<T>`, and you can't ever write `Vec` by itself, which is what a true higher-order type is (and what Functor needs: impl Functor for Vec { ... } impl Functor for Option { ... } Thus, your example isn't at all possible now or even in the near future.
- thinkpad20 12y agoI'm aware that my example isn't possible, which is why I said, "if they wanted to, they (presumably) could allow for..." My point being that Rust restricts what one can do with higher-order types, but those types still exist and are expressible in the language. From a theoretical point of view, there doesn't seem to be any reason that they couldn't allow for traits on higher-kinded types -- they simply choose not to. Perhaps for performance reasons, or for simplicity, or for syntax or whatever, but I haven't seen any reason why they couldn't. That was the point that I was making.