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.
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
Some more background on why IHP has a paid variant can be found here: https://ihp.digitallyinduced.com/blog/6392ad84-e96a-46ce-9ab...
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.
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.
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 :Ð 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 bAlso, 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 (,)
(,) :: * -> * -> *
[brief pause for contemplating the thought]
Naturally, someone went there: https://www.parsonsmatt.org/tutorials/
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?
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.
You can load your entire project in the repl and try your functions there.
I also don't see much jobs available.
Where do you see those job listings?