💾 Archived View for dioskouroi.xyz › thread › 25005525 captured on 2020-11-07 at 00:55:33. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

Real World Haskell

Author: Fiveplus

Score: 203

Comments: 61

Date: 2020-11-06 06:43:51

Web Link

________________________________________________________________________________

srg0 wrote at 2020-11-06 09:09:32:

I thought it was about the book and almost skipped the link. It would help to name it "Real World Haskell 2020" or something distinct.

Syzygies wrote at 2020-11-06 16:33:24:

Exactly. The book can't trademark the name in general use, but it's still crappy hygiene to reuse the exact name. This has to be taken as deliberately drafting the wake of the book, which I cannot respect. Nor can the authors feign ignorance. They decided to do this.

cies wrote at 2020-11-06 10:21:01:

Think the author should pick new title. This is plain confusing.

phonebucket wrote at 2020-11-06 09:24:15:

I also thought it was about the book and almost skipped this until reading your comment.

miguendes wrote at 2020-11-06 09:17:06:

Interesting. I've been programming in python for more than 4 years and I'd like to try something different.

I took a haskell class back in the day but just the basics, didn't even learn monads.

My goal is not to master the language itself but learn enough to make a better programner.

One thing that has been holding me back is the lack of real world examples. I get demotivated when only solving toy problems.

This looks like a great resource. I have heard a lot about Haskell From First Principles but there's too much stuff in there.

_query wrote at 2020-11-06 09:38:33:

To build some real world web applications check out IHP:

https://ihp.digitallyinduced.com/

It's a truly batteries-included way to get started with building real world haskell web apps in minutes.

dmix wrote at 2020-11-06 10:16:51:

Wow, if that matures, ie gets some real world adopt by serious companies it would be the best thing around.

Much like using Rust and Haskell for web I'd much prefer deferring as much to something like Vue and the server APIs (no sever side rendering for _that_ yet so I mostly just IRL use nuxt.js for toy projects). Something Servant (Haskell) does a clean job of. But you can never completely do away with static heavy lifting

This one takes a more modernized Rails or Elixir's Phoenix approach which is really interesting and looks highly usable.

Community size and quality is everything for real life software (something I remember Clojure had early on and now Rust has in spades, best of breed sort of libraries to choose from) so I hope it gets some adoption to see where it goes. I'll give it a shot to toy around with when I get some time.

vindarel wrote at 2020-11-06 17:04:55:

> Make sure you have good internet and can wait up to 30 minutes to complete the download [of version 16.10.2020]. We highly suggest to make sure your coffee machine is working before starting the update.

Wow!

_query wrote at 2020-11-06 17:22:59:

If you have good internet connection it's usually downloaded a lot faster. We have switched the nixpkgs version in that version, so a lot of tooling had to be redownloaded. E.g. in our getting started video we install it on a fresh empty macbook:

https://www.youtube.com/watch?v=PLl9Sjq6Nzc&feature=youtu.be

The full download there takes around 9 minutes on a slow home office internet connection (it's speed up in the video, but you can see the real-world time at the top right).

We mainly added the warning in that release because usually the update process is very smooth and takes only one minute, e.g. see this tweet:

https://twitter.com/mittie/status/1322574176792825861

miguendes wrote at 2020-11-06 14:11:43:

That's quite interesting. Thanks for mentioning it!

anentropic wrote at 2020-11-06 14:01:29:

Step 1: install nix

hmm, no thanks

_query wrote at 2020-11-06 15:30:59:

We did a blog post a while ago sharing why we decided to use nix for all package management aspects of the framework. Take a look:

https://ihp.digitallyinduced.com/blog/2020-07-22-why-ihp-is-...

justmyname wrote at 2020-11-06 14:46:53:

Install nix? Already done. What's the second step?

wtetzner wrote at 2020-11-06 15:02:47:

Why is installing nix any worse than installing some language-specific package manager?

whateveracct wrote at 2020-11-06 15:37:42:

Nix causes a visceral negative reaction in some people.

theCodeStig wrote at 2020-11-07 04:49:12:

Why?

girishso wrote at 2020-11-06 09:32:10:

You might want to give a try to Elm. Most of the Haskell goodies but way simpler, except no type classes and too restrictive.

tasuki wrote at 2020-11-06 12:31:34:

+1 for Elm to learn Haskell. It is indeed way simpler, and has very friendly error messages. It lets you concentrate on grokking the basics: no side effects, pattern matching, recursion, currying.

After some time you start wondering why you have to type `List.map` and `Maybe.map` and `Set.map` when they all do the same thing. Then you'll be ready for some Haskell :)

tiew9Vii wrote at 2020-11-07 00:57:52:

Not used Elm since early 2014 and heard it’s changed a bit since then.

Elm was a great Trojan horse. It limited feature set made it quick to learn and get familiar with the syntax.

When sufficiently proficient in Elm you then find yourself missing some of the features of Haskell i.e. higher kinder types. At that stage Purescript / Haskell is a natural transition as they feel familiar but with more functionality.

cies wrote at 2020-11-06 10:19:18:

Then PureScript also deserves a mention. It has several frameworks (some akin to the one built in in Elm). If you want to do this in Haskell (which is a lot harder) you may want to look at Miso.

miguendes wrote at 2020-11-06 14:11:00:

Thanks for the suggestion. I've heard people suggesting Elm on reddit but in terms of learning materials there isn't much compared to haskell. But I think that shouldn't be much of a problem.

I know that Elm works great for front end but how is it for desktop and backend stuff?

piaste wrote at 2020-11-06 14:17:55:

> I know that Elm works great for front end but how is it for desktop and backend stuff?

It isn't. It's explicitly designed as a purely web front-end language, that's its scope.

Of course, many Elm users like to run another ML-family language in the backend as well. Haskell's Servant backend library, the one used in this article, has a project to automatically generate Elm client code [1]. Elixir is popular as well.

But in general, I'd say that any backend framework that can provide an OpenAPI spec will work well, as you'll be able to auto-generate most if not all of the Elm client code (which is normally dull work and one of the main complaints about Elm).

[1]

https://github.com/haskell-servant/servant-elm

tasuki wrote at 2020-11-06 14:50:40:

Yes, no desktop and backend. It might be possible to use Elm outside of web frontend, but probably wouldn't be much fun.

> in terms of learning materials there isn't much compared to haskell.

To whet your apetite, see

https://elm-lang.org/

Then read through the excellent

https://guide.elm-lang.org/

- not very long but absolutely enough to hit the ground running.

girishso wrote at 2020-11-06 15:51:19:

Agreed official elm guide is more than enough to get “started” with real world examples.

dmix wrote at 2020-11-06 10:03:00:

Learning Haskell sideways is a good approach. There are so many usecases in JS as well and Typescript has made it all the better (but not nearly so restrictive).

WJW wrote at 2020-11-06 13:03:17:

I wrote a blog post some time ago on writing a small URL shortener in Haskell at

http://www.wjwh.eu/posts/2019-11-01-haskell-shorturls.html

. Still a toy example, but more "real world" than recursion exercises :)

the5avage wrote at 2020-11-06 10:38:11:

> One thing that has been holding me back is the lack of real world examples. I get demotivated when only solving toy problems.

I looked at haskell a few months ago and had a similar problem.

While I don't mind the toy problems, all those toy problems have something in common...

They can be easily solved with recursion. There are probably patterns to deal with other problems and this would have been more interesting to me.

I just had to think to myself: "If all you have is recursion every tutorial looks like a parser" ;)

chongli wrote at 2020-11-06 10:57:54:

Recursion is equivalent to iteration. You can solve any problem you like with it.

The problem with those tutorials is that they’re trying to do two things at once: 1) teach you Haskell and 2) advocate for Haskell.

I’m currently working as a full time assistant for one of the first year computer science courses at my university. This course is taught in a teaching dialect of Racket which does not allow mutation or side effects of any kind.

That doesn’t stop the profs from creating assignments with real world applicability such as graffiti stroke recognizers and decision tree learning algorithms. The key is that they’re not trying to make Racket look good, so the patterns of recursion can get pretty ugly at times.

the5avage wrote at 2020-11-06 15:48:26:

> Recursion is equivalent to iteration. You can solve any problem you like with it.

Maybe my comment was somehow badly written, because you (and

the only other reply from chriswarbo) clearly misunderstood me.

I know that recursion is equivalent to iteration^^

My point was that some problems fit the one or the other better.

Look at fft for example. The algorithm is easy with recursion but hard with iteration. For other problems its the opposite.

tasuki wrote at 2020-11-06 18:29:24:

Which problems are hard to solve with recursion instead of iteration?

the5avage wrote at 2020-11-06 21:05:57:

I found something like splitting a string into words not very intuitive...

Also the classical (recursive) fibonacci function everyone shows has accidental complexity of O(2^n). If you want a sane version it looks definitely more complicated than the iterative version.

I never saw a recursive version of bresenham's line plotting algorithm so this might be a good candidate as well ;)

a1369209993 wrote at 2020-11-07 04:01:10:

> splitting a string into words not very intuitive

It seems okay?

            split :: String -> [String]
  split s = w s "" where
    w [] "" = []
    w [] a = [reverse a]
    w (' ':ss) "" = w ss ""
    w (' ':ss) a = reverse a : w ss ""
    w (c:ss) a = w ss (c:a)

If you're done then you're done (and dump the accumulator), if it's a space get rid of it (and dump the accumulator), otherwise add it to the acuumulator. That the accumulator is stored backward is a bit wierd, but seems more a consequence of linked lists than recursion per se.

chongli wrote at 2020-11-06 22:19:31:

_I found something like splitting a string into words not very intuitive..._

Just use a couple of accumulators (one for the current word, one for the list of completed words).

_Also the classical (recursive) fibonacci function everyone shows has accidental complexity of O(2^n)._

That's moving the goalposts. If you want a really fast fibonacci function then the classical iterative algorithm [which is O(n)] is not what you want either. Better to use matrix exponentiation which you can implement nicely with recursion using a divide-and-conquer approach similar to mergesort, giving you fibonacci with time O(log(n)).

_I never saw a recursive version of bresenham's line plotting algorithm so this might be a good candidate as well ;)_

There's nothing special about Bresenham's line algorithm that would make it particularly challenging to implement with recursion.

chriswarbo wrote at 2020-11-06 14:46:04:

> While I don't mind the toy problems, all those toy problems have something in common...

> They can be easily solved with recursion.

As a sibling mentions, recursion is pretty much required in pure functional programming. There is no notion of time or sequencing: everything we write is a _definition_. If we don't call another function, then our program will finish; if we don't use recursion (either directly, indirectly via functions like `map`, or via a chain of mutually-recursive definitions) then our program's behaviour will be fixed by the structure of our _code_ (e.g. the number of calls we write). That's fine for simple calculations, but most useful programs depend on the structure of their _data_ (e.g. processing lines in a file, etc.); that requires recursion, since we can't hard-code the right number of calls ahead of time.

flubert wrote at 2020-11-06 19:33:04:

General recursion is equivalent to goto. It is nicer when recursion can be wrapped up in a higher level combinator (map, fold, etc.) or other even higher level abstraction. That's one thing the array languages (APL, J, etc.) got right.

chriswarbo wrote at 2020-11-06 20:08:55:

> General recursion is equivalent to goto.

Yes, but goto requires a whole bunch of machinery in order to make any sense. It (a) needs a notion of time/sequencing, (b) needs a notion of statement and (c) needs a notion of labelling.

(a) and (b) are often taken as given in imperative programming languages (e.g. C, assembly, etc.), but Haskell has none of them. It's hard to ascribe any meaning to "goto" in Haskell; other than some embedded language like ST or something.

> It is nicer when recursion can be wrapped up in a higher level combinator (map, fold, etc.) or other even higher level abstraction.

I agree, but I was counting those as (indirect) recursion for the purposes of explaining the parent's observation.

aszen wrote at 2020-11-06 17:58:43:

In my brief experience of going through the Haskell examples, I am awestruck by the power that Haskell enables yet scared by the huge type level complexity underlying the libraries that enable it.

Just to query a database the example used half a dozen langauge extensions.

I could probably learn the base Haskell langauge but that's not enough it seems for real world usage.

Now these langauge extensions ofcourse reduce the boilerplate and enable a nicer syntax but they dramatically increase the cost of using Haskell in production.

My understanding of the ecosystem is that there is a divide between people who want to use Simple Haskell concepts and others that want to advance the state of the start for every library.

https://www.simplehaskell.org/

strbean wrote at 2020-11-06 18:05:17:

I worked with Haskell for awhile but never had it fully 'click'. That being said, I think that once someone is fully comfortable with algebraic data types, category theory, and functional programming, most of these extensions and fancy constructs become pretty shallow and easy to understand.

(Would appreciate if any bonafide haskellers care to comment)

carterschonwald wrote at 2020-11-06 19:14:55:

Cat theory isn’t needed at all. It just gives you another smell test for recognizing you maybe designed an api nicely. (Aka: oh cool, my api code has some nice mathematical / logical property, maybe it’s not just mud on the wall)

tiew9Vii wrote at 2020-11-07 01:05:59:

Agree. You don’t need to know category theory to use Haskell or the libraries.

Know category theory or being aware of it just gives you a deeper understanding of the way things work.

I don’t know category theory but aware of it. The way I look at it is c style languages you have design patterns. These are loosely designed patterns with no formal definitions. That makes it hard to reason about or test things.

In category theory you have mathematical laws. Laws are far stronger than a loosely typed designed patterns so using these laws it’s far easier to reason about code.

bojo wrote at 2020-11-06 19:34:46:

Also piping in to say you don't need to understand category theory to successfully write production Haskell. It's interesting to learn and does help solidify understanding of some concepts, but by no means required.

Highly agree that most common extensions are pretty shallow and easy to understand. The tricky ones are usually enabled because some library told you to, or you've genuinely leveled up and recognize where to use them yourself.

ajarmst wrote at 2020-11-06 21:09:46:

I'm not convinced that arguing that _"think[ing] day-to-day tasks like running a web app are difficult or impossible in Haskell! ... isn't true!"_ is well-served by a series that introduces (in the first post!) Persist and Template Haskell and then has

{-# LANGUAGE TemplateHaskell            #-}
  {-# LANGUAGE QuasiQuotes                #-}
  {-# LANGUAGE TypeFamilies               #-}
  {-# LANGUAGE MultiParamTypeClasses      #-}
  {-# LANGUAGE GADTs                      #-}
  {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  {-# LANGUAGE RecordWildCards            #-}
  {-# LANGUAGE FlexibleInstances          #-}
  {-# LANGUAGE OverloadedStrings          #-}

  PTH.share [PTH.mkPersist PTH.sqlSettings, PTH.mkMigrate "migrateAll"] [PTH.persistLowerCase|
  User sql=users
    name Text
    email Text
    age Int
    occupation Text
    UniqueEmail email
    deriving Show Read
  |]

as literally the third block of code in the series. That's more of a proof of the opposite, don't you think?

saithound wrote at 2020-11-07 01:14:23:

Python web app tutorials routinely introduce MongoDB/pymongo, Flask, at-annotations for routing, and follow that up with 2-5 `from __future__ import` statements. These are pretty much exactly analogous to the steps in the current series. The only difference is that the Haskell standards change less frequently, so more "from __future__" imports (LANGUAGE pragmas) are required. (Note that the latest Haskell is from 2010, while the latest Python is from 31 days ago; see how many future imports you need to get a modern Python web app to work with a ten year old Python release)

This is not evidence that day-to-day tasks like running a web app are difficult or impossible in Python.

hda111 wrote at 2020-11-06 13:07:45:

I like how this website gives an overview first on what to expect. I wish more articles shared here would do this.

allenleein wrote at 2020-11-06 09:23:35:

For people who want to dig more, here are some free resources about learning Haskell:

https://github.com/allenleein/knowledge-base/tree/gh-pages/%...

danidiaz wrote at 2020-11-06 12:24:42:

This is a good way of getting your feet wet:

https://haskell-via-sokoban.nomeata.de/

kimburgess wrote at 2020-11-06 12:16:48:

Also, the unfortunately now de-funded, but still resource bearing

https://qfpl.io/projects/professional-fp-courses.html

.

cies wrote at 2020-11-06 10:42:48:

In the real of paid resources, I found this one most useful:

https://haskellbook.com

mraza007 wrote at 2020-11-06 20:44:13:

Can anyone share where’s haskell used

Like what companies are using haskell

elbear wrote at 2020-11-06 20:49:26:

Github are using it

https://github.com/github/semantic

Facebook and many others.

asplake wrote at 2020-11-06 17:47:57:

Immediately confronted by 9 compiler extension directives, major turnoff to this interested newbie. Is this considered normal and acceptable?

aszen wrote at 2020-11-06 18:02:14:

I think this is considered normal for real world Haskell usage.

Most libraries and even frameworks like ihp that try to be favor ease of use rely on these language extensions.

You can ofcourse place these directives once in the cabal file, but there's no getting around to learning what they do.

lallysingh wrote at 2020-11-06 19:51:32:

Yes. They're normal here, and you can consider them about as significant as an import statement, some context when reading the code, but nothing crazy.

The extensions are very well vetted, and new versions of the language standard can be summed up as "enable extensions a, b, c by default." Plus library changes, of course.

tome wrote at 2020-11-06 19:24:28:

Why a turnoff? "Extension" just means "language feature that is thoroughly well-specified, well-tested and widely used but hasn't made it into the language standard (partly because there hasn't been one for ten years)".

iso8859-1 wrote at 2020-11-06 21:09:21:

With GHC2021, you may soon be able to simply put that instead, and it will imply enabling all those individually.

https://www.reddit.com/r/haskell/comments/je1t82/does_the_id...

kccqzy wrote at 2020-11-06 20:56:34:

Are you looking at production code or pedagogical examples? For the former, it's totally normally to use compiler-specific features. If you are scared off by that, you'd be better served reading a book that introduces things little by little.

Ericson2314 wrote at 2020-11-06 14:42:38:

Ugh, why do we need to spread the world with highly dubious libraries like Esquilito and Servant...

nimih wrote at 2020-11-06 17:49:13:

What makes those two libraries, in particular, "highly dubious"?

Ericson2314 wrote at 2020-11-06 20:15:07:

- Persistent: tries to support way to many kinds of databases, ends up being lowest common demoninator dumb about all of them.

---- Just use PostgreSQL simple

- Esquilito, not comprehensive. I vaguely remember let through some bad SQL too

---- Use Beam

- Servant: the type level stuff is poorly executed nerd skateboarding. It either should be:

---- less type level and more simple-stupid

---- Use data kinds so the type level is less "un-kinded" and catch a lot of mistakes before they become _horrible_ term-level errors.

mrkeen wrote at 2020-11-06 17:32:19:

As a huge fan of Servant, have you got a replacement I should check out?

Ericson2314 wrote at 2020-11-06 20:20:29:

No ...but

I use github.com/obsidiansystems/obelisk/ at work (I work at the place that makes it). It does it's own thing for user-visible routes (for frontend and backend because automatic prerendering). It does a different thing for requests and live queries all of which are over websockets for simplicity.

Our routes stuff should be pulled out as a generic dual parsing-prettyprinting library (it and

https://hackage.haskell.org/package/tomland

are the same basic ideal, just need to remove the concrete HTTP / TOML specifics to get to the commonality).

I once started throwing together like servant but using data kinds in

https://github.com/ericson2314/matrix-client