
Getting It Done with Haskell - lelf
https://app.doxiq.com/d/rbczklzyvgczkfgh/Getting-it-Done-with-Haskell-pdf
======
raarts
I've been looking at learning Haskell for al the obvious reasons, but I've
been put off by all the lengthy and detailed introductions to the syntax, and
math oriented examples, that seem written by theoreticists.

What I would like (and in my opinion what Haskell needs to grow), is a more
practical introduction, like doing a database conversion, or writing some
network service. Syntax can be explained in passing. Does this exist?

~~~
codygman
What about html parsing/posting, api creation/consumption, and screen
scraping? It's what I've used Haskell for the most and would be happy to make
some introductory tutorials.

~~~
djur
Yes, please. There's a dearth of this kind of material.

~~~
codygman
I didn't write it, but I came across something that might be of interest to
you:

[http://pbrisbin.com/posts/writing_json_apis_with_yesod/](http://pbrisbin.com/posts/writing_json_apis_with_yesod/)

~~~
Bootvis
Wow, thanks for the follow-up! I will have to check it out later. Thanks
again.

------
gohrt
After spending a day installing virtual machines and cabal sandboxes, my
verdict:

Until Haskell ecosystem stabilizes and it is possible to install a complex
(many dependencies) library/tool without hitting cabal-version hell, nothing
much will get done in Haskell.

Highlights from my day, installing _released_ packages on my Mac:

1.

    
    
        next goal: scion-browser (user goal)
        rejecting: scion-browser-0.3.1, 0.3.0, 0.2.19, 0.2.18,    0.2.17, 0.2.16, 0.2.15,
        0.2.14, 0.2.13, 0.2.12, 0.2.11, 0.2.10, 0.2.9, 0.2.8, 0.2.7, 0.2.6, 0.2.5,
        0.2.3, 0.2.2, 0.2.1, 0.1.3.4, 0.1.3.3, 0.1.3.2, 0.1.3.1, 0.1.3 (conflict:
        aeson => text==1.1.0.0/installed-9bd..., scion-browser => text==0.11.*)
    

2.

    
    
        cabal: The following packages are likely to be broken by the reinstalls:
        unordered-containers-0.2.4.0
        case-insensitive-1.1.0.3
        network-2.4.2.3
        HTTP-4000.2.10
        Use --force-reinstalls if you want to install anyway.
    

3.

    
    
        [2 of 7] Compiling Language.Haskell.BuildWrapper.GHCStorage ( src/Language/Haskell/BuildWrapper/GHCStorage.hs,
           dist/dist-sandbox-7b4470b7/build/Language/Haskell/BuildWrapper/GHCStorage.o )
    
        src/Language/Haskell/BuildWrapper/GHCStorage.hs:305:32:
          Not in scope: data constructor ‘MatchGroup’
    
    

4.

    
    
         Resolving dependencies...
    

(searching the entire graph of dependencies, trying in vain for mny minutes,
to find a set of package versions that are mutually compatible)

------
duckingtest
I was toying with Haskell a few years ago, and I found it unpractical.

Sometimes it turns out you need to do something with IO somewhere, and now you
have to change all the functions down the way to use it. Similar issue is lack
of exceptions - Haskell just has a type enhanced version of 'return -1' from
C. Exceptions should be completely separate from successful execution paths.
Throwing exception from a pure function with type like Int -> Int requires
changes in everything that uses it. Common Lisp's condition system is much,
much better.

The third issue I remember was that all fields' names are global.

All of this makes it very hard to write the minimal working code now and
extend it later. Instead, you have to provide scaffolding for possible future
changes, or risk having to change everything.

Maybe there's some True Way of using Haskell which doesn't suffer from these
issues, but I haven't found it.

~~~
jeremyjh
Unfortunately I found it really takes a lot of work on practical programs to
get past the stage where you have these sort of doubts. Finding the motivation
to do so can be a chicken-in-egg type of problem.

Technically you are incorrect about exceptions needing to change the type of
pure functions, but in fact I would always prefer to return an Either and so
it does result in code changes up the stack. However it may not mean very many
changes to signatures; a function used by only one parent shouldn't be top-
level and doesn't need a signature. And the result is a function that captures
failure modes in its type, which means other consumers can't forget to handle
failure (though they can explicitly choose not to if they want to just throw
an exception on failure). This may feel a bit verbose and unwieldy at first
but it actually is very powerful once you know the techniques.

The concern about IO - you don't say this but a lot of people worry about
logging output to STDIO for debugging. But Debug.Trace will do this impurely
for debugging purposes. Otherwise its actually pretty rare that you write a
pure function that later turns out to need IO. IO should usually stay in top-
level functions that provide the over-all program / routine structure. I'm
only at a journeyman level with Haskell but I've written over 20,000 lines of
real code and can't remember ever really running into this problem, though I
did worry about it when just getting started.

------
a-saleh
When "Getting it Done with Haskell", how do you solve the JavaScript problem?
:)

~~~
johan_larson
There's a page that describes a range of solutions:

[http://www.haskell.org/haskellwiki/The_JavaScript_Problem](http://www.haskell.org/haskellwiki/The_JavaScript_Problem)

~~~
a-saleh
Do you use some of them in production?

I.E. I have fooled around with elm, but that is about it.

