[HN Gopher] Learn Haskell by building a blog generator - a proje...
___________________________________________________________________
Learn Haskell by building a blog generator - a project-oriented
Haskell book
Author : gilmi
Score : 206 points
Date : 2022-06-08 07:50 UTC (15 hours ago)
(HTM) web link (lhbg-book.link)
(TXT) w3m dump (lhbg-book.link)
| zeckalpha wrote:
| I have found Hakyll to be useful in this space, if you want to
| move from building your own to configuring/extending your own.
| Iceland_jack wrote:
| 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
| :D
| Iceland_jack wrote:
| 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
| gilmi wrote:
| 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
|
| l> :k (,)
|
| (,) :: * -> * -> *
| Iceland_jack wrote:
| 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
| gilmi wrote:
| 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 wrote:
| 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.
| gilmi wrote:
| Sounds like a generally reasonable approach to me.
| matijash wrote:
| 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.
| newaccount2021 wrote:
| hans1729 wrote:
| 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 wrote:
| The linked articles are actually about how to translate
| problems from an OOP perspective into idiomatic Haskell.
| ypeterholmes wrote:
| 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.
| danuker wrote:
| 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?
| rowanG077 wrote:
| You have testing libraries in Haskell just like in every other
| languages. For example:
| https://hackage.haskell.org/package/tasty
| gilmi wrote:
| When you create a project description for your project (for the
| package manager) you can define a library, executables and test
| suites.
|
| In the test suite you write your tests against the library. You
| can do that at any stage, even before writing a line of library
| code.
|
| But yes, Haskell also has a REPL that can be used to experiment
| with code.
| lgas wrote:
| In addition to the other good answers you've gotten, I would
| like to point out that Haskell has QuickCheck
| (https://hackage.haskell.org/package/QuickCheck) which, if I'm
| not mistaken, more or less pioneered property testing. Property
| testing libraries are available in many languages now but they
| never seem to be as capture the magic of QuickCheck. (There's
| also https://hackage.haskell.org/package/hedgehog which is sort
| of a "modern alternative" to QuickCheck but I still prefer the
| OG).
| jokethrowaway wrote:
| HUnit is a popular choice: https://mmhaskell.com/testing/test-
| driven-development
| jose_zap wrote:
| Yes, there is GHCi, the Haskell interpreter and repl comes
| bundled with the compiler.
|
| You can load your entire project in the repl and try your
| functions there.
| _query wrote:
| 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)
| froza wrote:
| 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 wrote:
| 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-e9
| 6a-46ce-9ab...
| rowanG077 wrote:
| I don't get it. How can it be part of the commercial
| version if it is not implemented.
| prophesi wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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.
| embwbam wrote:
| 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
| cosmic_quanta wrote:
| 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 wrote:
| 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.
| alephnan wrote:
| Is the website/book/blog self-hosting?
|
| https://en.wikipedia.org/wiki/Self-hosting_(compilers)
| gilmi wrote:
| No. It is built with mdbook[0].
|
| [0]: https://rust-lang.github.io/mdBook
| bwanab wrote:
| 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.
___________________________________________________________________
(page generated 2022-06-08 23:01 UTC)