News for hackers. Stuff that matters.
Re:Lisp and Haskell (2015) by ghostwriter on Thursday October 08, 2020 @07:09AM (#24717975)
Why does getUsers return Maybe [a] in the first place? It should be [a]. You can also implement your own version of length that works only with iterables of your choice. The language allows leveraging type constraints to achieve this, the fact that your team didn't use it doesn't indicate an inherent flaw in the type system you've been provided with. And if you want to go an extra mile, use liquid-base instead of base.
Re:Lisp and Haskell (2015) by jshholland on Thursday October 08, 2020 @10:11AM (#24719221)
There is a substantive difference between "couldn't get any users because of an error" (Nothing) and "succeeded but found no users" (Just []).

But, if that really is the reason for Maybe [a] over [a], I'd still prefer Either SomeUsefulErrorType [a].

Re:Lisp and Haskell (2015) by ghostwriter on Thursday October 08, 2020 @10:56AM (#24719651)
Right, so we essentially say that the provided example doesn't refute the "it works if it compiles" slogan. It just works according to the provided specification expressed in the types, and it so happened that the specification was not specific enough.

My specification doesn't make a distinction between absent users and possible error responses because I assume that errors will be processed elsewhere and the getUsers function is applied as part of the "safe core" interface that is not concerned about error handling. If the specification was more precise (even more precise than in your suggestion, for instance, getUsers :: SafeIterable a => Foo -> a and length :: SafeIterable a => a -> Integer ), it would work differently.

The issue in the example has to do with the clarity of the intent encoded in the type signature, not the inherent issue of the type system that cannot guarantee safe runtime of the example. That's why I mentioned type constraints for specific iterables as a possible solution to the encoding problem.

A better example of the compiled-but-not-working case would be something that currently cannot be expressed well by the type system, something like async exceptions or access to closed resources (will be covered by linear types soon).

Re:Lisp and Haskell (2015) by marcosdumay on Thursday October 08, 2020 @03:10PM (#24722629)
Of course, "if it compiles it works" depends on you designing good types.

Haskell will never stop you from representing every value as String, and just throwing exceptions if the strings do not convert back, for example.

Re:Lisp and Haskell (2015) by dunefox on Thursday October 08, 2020 @10:36AM (#24719427)
`Either` would be much better, no?
Re:Lisp and Haskell (2015) by 08-15 on Thursday October 08, 2020 @10:52AM (#24719598)
No, because `Either` is a `Foldable`, too.

I know, not what you meant. But a custom sum type would not only allow you to return multiple different failure cases, you also wouldn't give it a `Foldable` instance with surprising semantics.

Plain old data types are seriously underrated these days.