Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> - Higher-kinded types (template template params): it's possible to implement Haskell-style monads etc. in D, if for some reason you felt the need.

Because the templates aren't typed at all. I'm not sure you can call untyped templates "Haskell-style".



While the templates are technically untyped (in the sense that there are no type-classes or traits in D), you can use template constraints to achieve something similar: https://dlang.org/concepts.html. Essentially you'd write a compile time isMonad predicate that only returned true if certain functions were defined for a type.

Even without that, the key thing is it's still possible to implement monads in the C++ style (https://stackoverflow.com/a/2565191/2553416), whereas it's impossible to write code to do the same thing in current Rust. It just gives much worse compiler errors if you use it wrong compared to if the language had built in type-classes / traits.


Template constraints aren't the same thing as typed generics. The key issue is that typed generics influence the typechecker. For example, you can write "let x = Default::default(); f(x);" and the compiler can determine the type of x from the type of f.

Also, there is the "higher" crate for higher-kinded types if you need them, so it is possible to write a monad typeclass in Rust. It's not exactly something you'd want to use, though.


>For example, you can write "let x = Default::default(); f(x);" and the compiler can determine the type of x from the type of f.

That would be less helpful in C++/D because their compilers don't do Hindley-Milner style bidirectional inference, so even if they had typed generics they wouldn't necessarily be able to do that inference. But I suppose that's an argument in favour of Rust, stronger type inference.

>It's not exactly something you'd want to use, though.

Ergonomic HKT can make writing various kinds of utilities easier. E.g. imagine I want to write a function Singleton that takes a collection C (vector, list, stream...) and an item of type T, and returns C<T>, a collection containing a single instance of that type. I can write that in Haskell, D or C++, but not in Rust. Or perhaps more usefully, a function Fill, that returns a container C containing n items of type T. For Rust it seems I'd need to write a separate implementation of Fill for each container type, I couldn't write one parameterised over any C?


You can do that without HKT, using FromIterator (which is also used by the widely used iterator method "collect").

Here is an implementation: https://play.rust-lang.org/?version=stable&mode=release&edit...

Fill is also possible, using the same trait and iterators.


I stand corrected. Could the same technique also be used to have a struct parameterised by C and T that had a C as a member?


You can't partially apply type parameters in rust, that is HKT. But traits & associated types in traits get you pretty far.


"wouldn't necessarily be able"

It goes completely against the most (perhaps) fundamental part of C++ philosophy of overloading functions on argument types.


Overloading does not conflict with type inference: it just means that type annotations are sometimes necessary to get down to concrete types for execution. From "f(x)" we can infer that the type of x is one of f's overloaded argument types.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: