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

I always thought that what makes Haskell particularly readable are the types: to understand what a function does, it is often enough, and always helpful, to understand what type it takes to what types.

So, when the first type I see in a Tutorial is

    Resource IO (ReaderT Title IO) Title () Void
I am confused. When, in addition, the functions are named

     mkResourceReader :: ??? -> Resource IO (ReaderT Title IO) Title () Void
I lose hope that I'll ever understand what's going on. Granted, it was only recently that I understood what 'ReaderT Title IO' alone means.

I wonder, is there a simple explanation for what's going on, or is the problem at hand really so complicated that this is the easiest way to explain it?

For example, maybe there should be a shorter and clearer name for the type 'Resource a (ReaderT b a) b () Void'? What does one do with resources -- I can only see them plugged into the 'route' function.

At this point I started cursing that I can't find the Haddock documentation anywhere, and I'm too lazy to search through github.

I'm sorry if this comes across as unfriendly to the author of the library, but I hope it's helpful to see what a person who tries to understand what it does might go through. The more I look at it, the more I think that everything could be fixed with a better tutorial.

EDIT It's late at night, and I'm rambling, but perhaps it would be enough to explain in the tutorial what the composition

    route . mkResourceReader
does, and what its type is? It seems like that might be tractable.


I think your comments are valid and I mostly agree very much with this sentiment. Thank you for sharing.

But let's look at it differently.

This framework has been developed and shaped over a few years in a corporate environment by a small team of relatively experienced Haskell programmers. The code has been shaped and tweaked to specifically tailor all the needs we had at Silk for a effortless development of a very consistent REST API for our core product. The code solves a lot of problems at once.

We never developed this framework as a minimal library for public use. But, because it solves and actual problem for us and is very general purpose we felt obliged to open source it. This might be very useful for other as well.

One of incentives for a company to open source an internally used framework is to get community feedback that might end up shaping the software to be simpler, more generally applicable and more battle tested. That's why your critique is useful and exactly one of the reasons to opens source.

To go more in the why the types for a Resource are what they are right now:

- In a real world example your API probably doesn't run in IO, but in some monadic context that allows acces to you database, configuration settings, log server, S3 buckets etc.

- Resources contain a schema type that statically enforce the invariant that no routes will ever overlap in the server.

- A single resource, or multiple resources, can be identified by multiple identifiers (e.g. a user by uuid, e-mail, or last name). We require a total mapping from identifier to resource action.

- While stepping deeper into an API (path segment by path segment) we can learn more about our context and pass information down to sub-resources. We do this by extending the context, in the simplest case with a reader.

- The `route` function builds up an existential. So it looks like the type of the Resource is irrelevant and could be one simple type synonym, but it isn't. It's different every time and carries a lot of static information about the resource used at runtime, and for code and documentation generation.

We'd love to hear how we can simplify this.


There's nothing wrong with what you are doing. There is no law that states that all open source libraries in the world should be perfectly documented, and have a set of tutorials that would gently teach anyone as much as he wants about how to use it. Writing documentation and/or tutorials is hard work, and the larger your target audience is, the harder and more time-consuming it is.

I don't think your library will be generally useful to a large audience until you or someone else writes better documentation for it. But you don't have to target a large audience. It's quite likely that when someone else has the same problem, it would be faster for them to reuse your library than to write their own. They might even document the process.

I don't think I'm qualified to give any specific advice, but here's some general suggestions which may or may not be to the point. If you are sufficiently motivated, you should decide who your target audience is, and write enough documentation for them. For example, for an advanced audience, it might be useful to say a few words the general design of your library, explain which problems your library does solve and (more importantly) what the limitations of the design are, perhaps outline anything in the design that is strange or unexpected, but useful from your experience. The most important thing for them to know quickly is whether your library can actually solve their problem (which is probably slightly different from the problem you solved), whether it is actually faster to use your library than to roll their own. If they really need to, they'll figure out the rest. The end result might be closer in style to a CS paper than a tutorial.

Oh, and one thing you really should fix: it is annoying that the haddock documentation is not available on Hackage at the moment, and probably not searchable on Hoogle as well.

Again, there's nothing wrong with your library, you are doing a good thing open sourcing it, and any time you put in describing it and explaining it to people is valuable. Just keep doing more of what you are already doing.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

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

Search: