4 ms·
Not the OP, but I remembered writing something in Haskell, and being extremely frustrated when I chose to model something as a List.NonEmpty, because it wasn't
by yen223 8y ago
Not the OP, but I remembered writing something in Haskell, and being extremely frustrated when I chose to model something as a List.NonEmpty, because it wasn't straightforward to pass them around to functions that expected List.
- hardwaresofton 8y agoMaybe it's the stockholm syndrome talking, but this sounds like a feature to me -- The type that represents a non-empty list and one that can be empty are distinct. If a function is a mapping of inputs to outputs, then those two functions are (and should be treated as?) distinct, despite the fact that one result space is clearly the subset of another. The problem is I don't know much about the List.NonEmpty type -- it seems like it would be almost trivial to implement it while maintaining List-compatability, but clearly it's not (and was frustrating to use) so... Your point is definitely true, some things like that are very frustrating to deal with in Haskell -- especially when you expect something like that to 'just work' and it doesn't.
- Zalastax 8y agoI would not call it a feature. The clean solution would be dependent types so we can model the proposition "that list is not empty" in the type system. It is very neat to have the standard list as your data-type, but accompanying it is a proof that the list has elements. However, dependent types are not mainstream yet and we need a lot more research before that can change.
- gizmo686 8y agoHaskell does not have OOP style inheritance. If you define a new type, it is impossible to use it where you were expected a value from a concrete old type. The way around this is typeclasses, which are essentially interfaces. But this would require that the functions you are calling (which may be written by a third party) be written against a generic typeclass instead of the concrete List type. Haskell is improving in this regard, but there is still many places that are written expecting a List. Also, if the function needs any beyond simple iteration, the typeclass it would use would have a scary name like Semigroup (even iteration uses Foldable, which might not be clear to beginners) There is the IsList typeclass. But the intended use for that is to enable a list-like datatype to be represented with list literals in source code. Even with all of these difficulties, the worst case scenario is to spam your code with NonEmpty.toList and NonEmpty.fromList (or its safe sister NonEmpty.nonEmpty which returns an error value instead of throwing when given an empty list.