Hacker News new | ask | show | jobs
by josephcsible 810 days ago
> In Rust and Haskell you have to at least annotate the parameter types and return type of functions.

In Rust you do, but in Haskell you don't.

2 comments

What about when writing a function with polymorphic recursion, rank-N types, or the monomorphism restriction?

There are plenty of examples where a type declaration is required to get functionality, especially when we consider what GHC offers as being "Haskell".

I agree the author could be more clear about this—that Haskell and GHC only sometimes require type annotations in certain circumstances.

To be clear these are extremely rare circumstances. You virtually never need type annotations.

And even in some cases where you used to need them a simple type application is often enough now.

You can go an entire career without writing a single type annotation. It depends heavily on what style of Haskell you write.

In Haskell the culture is to always do it, more or less for this reason.
For top level functions maybe, but certainly not for helper functions defined in let ... in, or where clauses.
Haskell, or hlint, also has the concept of eta reduce which removes documenting variable names. Just awful.
The eta reduction code hint is a weird one for sure, although let's be real with Haskell naming conventions that usually means dropping an 'x'.

If the linter cares so much about making code point-free maybe they should start suggesting refactors like

    foo x = bar x (baz x)
to

    foo = bar <*> baz
(... /s)
Or another example:

  where
  genBranchLabels = do
      (,,,) <$> freshBranchLabel "if_"
            <*> freshBranchLabel "then_"
            <*> freshBranchLabel "else_"
            <*> freshBranchLabel "endif_"
instead of:

  Cg<Tuple4<String, String, String, String>> genBranchLabels() {
      return freshBranchLabel("if_")
               .flatMap(i -> freshBranchLabel("then_")
                 .flatMap(th -> freshBranchLabel("else_")
                    .flatMap(el -> freshBranchLabel("endif_")
                      .map(ei -> new Tuple4<>(i, th, el, ei)))));
  }