Settings

Theme

Learn Haskell by building a blog generator – a project-oriented Haskell book

lhbg-book.link

230 points by gilmi 4 years ago · 41 comments (40 loaded)

Reader

cosmic_quanta 4 years ago

That's the perfect learning project because there's something tangible at the end.

Whenever the question of "How do I learn Haskell" comes up, I always suggest to come up with a project that would be useful on its own, regardless of the technology used to create it, and use Haskell to do it. In my case it was a pandoc filter to embed plots in documents (https://github.com/LaurentRDC/pandoc-plot), which was ultimately useful to create my PhD dissertation.

There's only so much you can learn about Haskell by working through toy examples.

  • cholantesh 4 years ago

    Great project; I'd have loved to have had it when I was writing my dissertation - hell, I'd have liked anything that would have let me write it in vim and just generate the final submission per the university's format, because I hate Word.

_query 4 years ago

If you want to do web development with Haskell beyond building a blog generator, a good starting point is IHP (https://ihp.digitallyinduced.com/ https://github.com/digitallyinduced/ihp). IHP is Haskell's version of Laravel/Rails/Django. It's really a superpower to have Haskell's type system combined with the rapid development approach of Rails :) (Disclaimer: I'm founder of the company that makes IHP)

  • embwbam 4 years ago

    I think IHP for learning Haskell has the same flaw that Rails always did. You have no idea what is part of the language and what is part of the framework. You'll get stuck once you stray from the golden path.

    I'd recommend starting with Scotty instead. It's much easier to understand what it is doing. Use Lucid for HTML rendering, and your choice of DB libraries (I like Selda). These all avoid template haskell and don't rename any prelude functions. If you add them one at a time you'll see what each one is offering and understand where to go when you need to do something more complicated

  • froza 4 years ago

    I was tempted to try it, but then I saw that some core features (like mysql) are for paid versions only so its a big red flag already

    • _query 4 years ago

      Mysql support is not implemented at the moment. If there's someone paying for the development we could have it. You're of course also free to contribute it yourself to the open source version, then it wouldn't need to be part of the commercial version.

      Some more background on why IHP has a paid variant can be found here: https://ihp.digitallyinduced.com/blog/6392ad84-e96a-46ce-9ab...

      • rowanG077 4 years ago

        I don't get it. How can it be part of the commercial version if it is not implemented.

        • prophesi 4 years ago

          Not OP, but it sounds like MySQL support isn't out yet. So I think the business plan can help them get paid to implement it. No clue if that means the FOSS version would receive those upstream changes once it's done.

    • cultofmetatron 4 years ago

      software needs work and devs have bills. its unfortunate but we don't have a government currently giving grants to open source devs yet.

  • bitmapper 4 years ago

    I'm really not a fan of IHP for that purpose due to how it redefines so much of the Haskell Prelude without making it clear it does that.

  • My71staccount 4 years ago

    Ah, I was wondering why you post about IHP on most Haskell threads here and I just noticed it is a commercial product. You should probably disclose that this is an advertisement if it is permitted at all.

    • _query 4 years ago

      IHP is mostly an open source project.

      I comment on most Haskell threads about IHP because I would love to see more Haskell adoption. Most people think Haskell is about Monads and Math, with IHP we want to show that Haskell can be used in a very productive way to build things. The comments are typically well received, so I don't see any problem with this.

matijash 4 years ago

This is really cool! I've been looking for something like for a while - my learning path was through LYAH and Real-World Haskell (also tried Haskell from the first principles but a bit too extensive IMO). I think this would fit in perfectly between LYAH and RWH.

I am using Haskell mostly for writing compilers (https://github.com/wasp-lang/wasp currently), but I believe if the tutorial isn't using a lot of specialized libraries/frameworks (which seems to be the case from the first glance), a majority of the material taught should be transferable to any domain.

bwanab 4 years ago

If you’re more inclined to visual and/or musical arts, I’d recommend “Th Haskell School Of Expression” by Paul Hudak. He guides you through the language and the techniques with an eye for concise, expressive code that has good runtime characteristics.

mbrodersen 4 years ago

Kudos to the author. The best way to teach something is to start with a foundation of nothing and then step by step building layers of understanding on top of it. Most other Haskell tutorials fail to do this.

Iceland_jack 4 years ago

Oh this looks fun getStructureString and render can be defined as record selectors

  newtype Structure = Structure { getStructureString :: String }
  newtype Html      = Html      { render             :: String }
BlockArguments let you write expressions like myhtml

  myhtml :: Html
  myhtml =
    html_
      "My title"
      ( append_
        (h1_ "Heading")
        ( append_
          (p_ "Paragraph #1")
          (p_ "Paragraph #2")
        )
      )
in a more domain-specific style. De gustibus, but some may prefer it to the parentheses.

  {-# Language BlockArguments #-}

  myhtml :: Html
  myhtml =
    html_ "My title" do
      append_
        do h1_ "Heading"
        do append_
             do p_ "Paragraph #1"
             do p_ "Paragraph #2"
or using the associativity of append_ = (<>)

  myhtml =
    html_ "My title" do
      h1_ "Heading" <> p_ "Paragraph #1" <> p_ "Paragraph #2"

  myhtml =
    html_ "My title" do mconcat
      [ h1_ "Heading"
      , p_ "Paragraph #1"
      , p_ "Paragraph #2"
      ]
All examples of 'concat . map' can be replaced with.. concatMap :Ð
  • Iceland_jack 4 years ago

    Instead of defining append_ for structure

      newtype Structure = Structure String
    
      append_ :: Structure -> Structure -> Structure
      append_ (Structure c1) (Structure c2) = Structure (c1 <> c2)
    
      empty_ :: Structure
      empty_ = Structure ""
    
    the <> operator (from Semigroup) can be reused by deriving it via the underlying String type (edit: I see this is suggested later in the tutorial).

      {-# Language DerivingStrategies         #-}
      {-# Language GeneralizedNewtypeDeriving #-}
    
      newtype Structure = Structure String
        deriving
        newtype (Semigroup, Monoid)
    
      append_ :: Structure -> Structure -> Structure
      append_ = (<>)
    
      empty_ :: Structure
      empty_ = mempty
    
    Semigroup and Monoid let us use a lot of standard vocabulary

      concatStructure :: [Structure] -> Structure
      concatStructure list =
        case list of
          [] -> empty_
          x : xs -> x <> concatStructure xs
    
    becomes

      concatStructure :: [Structure] -> Structure
      concatStructure = mconcat
    
    or

      concatStructure = fold
    
    Also in the detour about kinds they are written as * while the ecosystem is moving towards a more uniform Type name.

      {-# Language StandaloneKindSignatures #-}
    
      import Data.Kind (Type)
    
      type Tuple :: Type -> Type -> Type
      data Tuple a b = Tuple a b
    
      type Either :: Type -> Type -> Type
      data Either a b = Left a | Right b
    • gilmiOP 4 years ago

      Right but the point of the book is to ease learners into the language (and teach core concepts), and not throw them into the deep end of it.

      Also, I'll update the text about kinds when GHC will use Type instead of * everywhere:

      $ ghci

      GHCi, version 9.2.2: https://www.haskell.org/ghc/ :? for help

      λ> :k (,)

      (,) :: * -> * -> *

      • Iceland_jack 4 years ago

        Not critiquing, I was giving a stream of consciousness while reading. I enjoyed it

        Until we get Type by default the best we can do is enable NoStarIsType

        • gilmiOP 4 years ago

          Thank you. I'm glad you're enjoying it. Sorry if I sounded a bit aggressive here.

          I think one of the cool things about Haskell is that there's quite a high ceiling in terms of solutions you can reach for. On many occasions when one get annoyed by something and thinks "there must be a better way", there is one.

          You show how one with more knowledge and command of the language can make it do a lot of things for free, and that is very cool! But I can also see how these solutions can look a bit intimidating for people with less experience, and it's important to take this into account as well.

          This is kind of a double edged sword. Gotta find the right balance.

          • Iceland_jack 4 years ago

            I didn't take it as aggressive. I hope people who are curious get something out of my comment but without intimidating others, perhaps I write it as a bonus that people can ignore if it doesn't help but you are right that some people could be put off by it.

zeckalpha 4 years ago

I have found Hakyll to be useful in this space, if you want to move from building your own to configuring/extending your own.

hans1729 4 years ago

At first sight I’ve read “an object-oriented Haskell book”.

[brief pause for contemplating the thought]

Naturally, someone went there: https://www.parsonsmatt.org/tutorials/

  • greymalik 4 years ago

    The linked articles are actually about how to translate problems from an OOP perspective into idiomatic Haskell.

danuker 4 years ago

How you would write tests in a real project?

I suppose it's not writing out the entire program and then writing the tests, as seems to be implied. That would mean a lot of manual testing.

Or is there a Haskell REPL where you can try out small pieces before saving them?

ypeterholmes 4 years ago

For anyone that does decide to learn Haskell, you can easily get a job afterwards working on the Cardano blockchain. Smart contract devs are in high demand, and Cardano uses a variant of Haskell that is relatively unique to the space.

  • heldrida 4 years ago

    I've been following for at least a year and find that the jobs pay is very low in comparison to Rust; or Solidity.

    I also don't see much jobs available.

    Where do you see those job listings?

alephnan 4 years ago

Is the website/book/blog self-hosting?

https://en.wikipedia.org/wiki/Self-hosting_(compilers)

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection