I am going to update this wiki as I am learning Haskell, and reading your comments.
Learning Haskell was quite hard for me, and I needed to be confident that my own code really works, and under which conditions. This is may be the same for you.
The reasons for the difficulties in learning Haskell, may be:
I consider myself a techie since I was a curious child. At an age of approximately 8 years, I assambled an electric DC Motor, and believe still to remember that I was shocked and amazed that it worked. I was so keen to understand…
This craving to understand is a very big driver - for me.
Just to imagine how rich Haskell is in terms of abstraction - and to understand how must can be and sometimes has to be understood - enyoy the example below.
The following shows how 10 primes are evaluated and displayed starting with the one millionth prime number.
module Main where import qualified Data.List as L main :: IO () main = do print ((genericTakeFrom 1000000 10 primes) :: [Integer]) genericTakeFrom :: Integral a => a -> a -> [a] -> [a] genericTakeFrom nFrom nCount l = L.genericTake nCount ((L.genericDrop nFrom) l) primes :: Integral a => [a] primes = 2 : [n | n <- [3, 5..], all ((> 0).rem n) [3, 5..floor.sqrt$((fromIntegral n) :: Double)]]
[15485867,15485917,15485927,15485933,15485941,15485959,15485989,15485993,15486013,15486041]
To understand this code (8 lines of code) completely I have to understand the following:
do-notationAnd there is also
)1 The code may not work with extrem large numbers. I do not know at which conditions the floor function would fail. My calculator says sqrt((1E16x1E16)-1) is 9.999.999.999.999.999,9999999999999999, but sqrt((1E17x1E17)-1) is (1E17)!
The following code (sieve of Erastothenes) will also work but by far not as fast for large numbers (approximately 100 times slower for the first 20 thousand prime numbers):
primes = let sieve (n0:lrn) = n0 : sieve [ n | n <- lrn, n `mod` n0 /= 0 ] in sieve [2..]
)2 The code compiles without any warnings with ghc 8.10.4 and option -Wall.