Code Monkey home page Code Monkey logo

haskell-mooc's Introduction

Haskell MOOC

Course logo

University of Helsinki

Course page

License: CC BY-SA 4.0

This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

New! Exercise repository updated to use GHC 9.2.8! You'll need to rerun stack build.

About the course

This is an online course on Functional Programming that uses the Haskell programming language. You can study at your own pace. All the material and exercises are openly available.

The course is intended to be followed through the Course page, but in case the course page is down or you want an offline backup, the course material is also available in this repository (part1.html, part2.html).

Exercises

Exercises can be found under exercises/ directory. All required dependencies can be downloaded and built with:

stack build

Exercises are Haskell source code files named Set1.hs, Set2.hs and so on. You complete the exercises by editing the file according to the instructions in the file. You can check your answers by running

stack runhaskell SetXTest.hs

in the exercises/ directory. Remember to replace X with the number of the set you are working on.

See the material for more info.

Troubleshooting

Here are some fixes for common problems with stack build:

  • If you get an error like While building package zlib-0.6.2.3, you need to install the zlib library headers. The right command for Ubuntu is sudo apt install zlib1g-dev.
  • If you get an error like Downloading lts-18.18 build plan ... RedownloadInvalidResponse, your version of stack is too old. Run stack upgrade to get a newer one.

Reporting errors

If you notice an error in these materials, you can report it via

haskell-mooc's People

Contributors

opqdonut avatar pllk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

haskell-mooc's Issues

Stack build fails

Ubuntu 22.04.1 LTS. Components used:

stack: 2.9.1
gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0

Stack build fails as follows:

$ stack build
Writing implicit global project config file to: /home/acb/.stack/global-project/stack.yaml
Note: You can change the snapshot via the resolver field there.
Using latest snapshot resolver: lts-19.25
Preparing to install GHC (tinfo6) to an isolated location.
This will not interfere with any system-level installation.
Downloaded ghc-tinfo6-9.0.2.
Unpacking GHC into /home/acb/.stack/programs/x86_64-linux/ghc-tinfo6-9.0.2.temp/ gcc: error: unrecognized command-line option '--target=x86_64-unknown-linux'
Installed GHC.
Error parsing targets: The specified targets matched no packages.
Perhaps you need to run 'stack init'?

Unable to do the Exercises.

Set16a Ex6: Possible unintended way to pass tests

Should tests for ex6 accept a generator which always produces a list of repeating values?
For example list [1,1,1] satisfies all properties given in description, so 'solution' like this feels like sidestepping the problem:

genList :: Gen [Int]
genList = do n <- choose (3,5)
             e <- elements [0..10]
             return (replicate n e)

If not then something like this could be reasonable unlikely to raise false positives:

ex6_2 = once $ testGenMany genList 30 $ \ls ->
  conjoin [counterexample "  should have lists of all lengths" $ nub (sort (map length ls)) ?== [3,4,5]
          ,counterexample "  should at least 7 different ints" $ length (nub (sort (concat ls))) >= 7
          ,counterexample "  should not have only single repeating int" $ any ((> 1) . length . nub) ls]

so above example fails with:

*** Failed! Falsified (after 1 test):
Generated values: [[8,8,8,8,8],[4,4,4,4,4],[8,8,8,8,8],[8,8,8],[4,4,4,4,4],[4,4,4,4],[6,6,6],[1,1,1,1,1],[6,6,6],[2,2,2,2,2],[5,5,5,5],[3,3,3],[7,7,7],[4,4,4,4,4],[5,5,5,5],[1,1,1],[0,0,0,0],[6,6,6,6],[1,1,1,1,1],[10,10,10],[2,2,2],[7,7,7,7],[0,0,0],[6,6,6],[9,9,9,9,9],[6,6,6,6,6],[9,9,9,9,9],[0,0,0,0,0],[5,5,5],[4,4,4,4,4]]
should not have only single repeating int

Use HTTPS for external links when possible (round 2)

Similar to my previous issue #26 created and resolved almost three years ago, this issue mainly focus on Part 2 and the site for book Real World Haskell.

To be updated to HTTPS (filtered by grep -rn --exclude-dir=img 'http:' .)

I didn't take the Part 2, hence don't know if localhost URLs in part2.html and its exercises support HTTPS or not.

Remaining HTTP-only site

Set14bTest.hs doesn't close the database connection which leads to incorrect testing

In Set14bTest.hs when testing ex. 1 & 2 (simple sql), doesn't close the database connection leading to incorrect testing and a database leaking from one test to the other. Running the test multiple times, we see that the length of the getAllQuery increases with every test run. I don't find any issues in the testing code. A bad and very temporary fix might be to always make a new random name when making a sql database in the tests.

===== EXERCISE 1
*** Failed! Falsified (after 1 test):
After running
  db <- openDatabase ""
  deposit db (T.pack "d") 1
  deposit db (T.pack "g") 7
The output of: query_ db getAllQuery :: IO [(String,Int)]
  Expected: [("d",1),("g",7)]
  Was: [("n",6),("k",0),("j",8),("q",7),("u",5),("u",7),("t",0),("m",10),("y",4),("u",0),("u",3),("c",3),("a",9),("p",8),("j",8),("j",1),("j",7),("o",8),("h",9),
("j",4),("j",2),("t",9),("f",9),("e",5),("t",8),("t",5),("j",9),("z",7),("z",10),("w",0),("w",9),("a",5),("a",1),("b",6),("a",2),("a",9),("l",9),("c",4),("e",1),
("e",6),("e",10),("y",10),("p",1),("w",5),("v",6),("v",10),("g",5),("g",0),("rh",10),("rh",10),("v",8),("v",9),("j",1),("i",10),("v",7),("t",9),("t",5),
("v",3),("t",0),("n",7),("h",8),("h",1),("e",8),("n",0),("o",9),("o",10),("o",7),("r",8),("d",1),("g",7)]

----- Fail
===== EXERCISE 2
*** Failed! Falsified (after 2 tests):
After running
  db <- openDatabase ""
  deposit db (T.pack "a") 0
  deposit db (T.pack "a") 7
The output of: balance db "a"
  Expected: 7
  Was: 33

*** Failed! Falsified (after 1 test):
After running
  deposit db "b" 0
The output of: balance db "f"
  Expected: 0
  Was: 9

----- Fail
===== EXERCISE 3
00000 Todo
===== EXERCISE 4
00000 Todo
===== EXERCISE 5
00000 Todo
===== EXERCISE 6
00000 Todo
===== EXERCISE 7
TODO
TOD00000 Todo
===== EXERCISE 8
00000 Todo
===== TOTAL
00______
0 / 8

If there is a possibility that it is a me problem, here is my code for the exercises:
ex.1

initQuery :: Query
initQuery = Query (T.pack "CREATE TABLE IF NOT EXISTS events (account TEXT NOT NULL, amount NUMBER NOT NULL);")

depositQuery :: Query
depositQuery = Query (T.pack "INSERT INTO events (account, amount) VALUES (?, ?);")

getAllQuery :: Query
getAllQuery = Query (T.pack "SELECT account, amount FROM events;")

-- openDatabase should open an SQLite database using the given
-- filename, run initQuery on it, and produce a database Connection.
openDatabase :: String -> IO Connection
openDatabase dataBaseName = do
                              db <- open $ dataBaseName ++ ".db"
                              execute_ db initQuery
                              return db

-- given a db connection, an account name, and an amount, deposit
-- should add an (account, amount) row into the database
deposit :: Connection -> T.Text -> Int -> IO ()
deposit db account amount = execute db depositQuery (account, amount)

ex. 2

balanceQuery :: Query
balanceQuery = Query (T.pack "SELECT SUM(amount) FROM events WHERE account = ?;")

balance :: Connection -> T.Text -> IO Int
balance db account = do
                        nums <- query db balanceQuery [account] :: IO [[Int]]
                        return . sum . head $ nums

Add fmap tests for Set 13b Exercise 7

The Exercise 7 of Set 13b is as follows:

------------------------------------------------------------------------------
-- Ex 7: here is the Result type from Set12. Implement a Monad Result
-- instance that behaves roughly like the Monad Maybe instance.
--
-- That is,
--   1. MkResult behave like Just
--   2. If part of computation produces NoResult, the whole computation
--      produces NoResult (just like Nothing)
--   3. Similarly, if we get a Failure "reason" value, the whole
--      computation produces Failure "reason"
--
-- Examples:
--   MkResult 1 >> Failure "boom" >> MkResult 2
--     ==> Failure "boom"
--   MkResult 1 >> NoResult >> Failure "not reached"
--     ==> NoResult
--   MkResult 1 >>= (\x -> MkResult (x+1))
--     ==> MkResult 2

data Result a = MkResult a | NoResult | Failure String deriving (Show,Eq)

instance Functor Result where
  -- The same Functor instance you used in Set12 works here.
  fmap = todo

-- This is an Applicative instance that works for any monad, you
-- can just ignore it for now. We'll get back to Applicative later.
instance Applicative Result where
  pure = return
  (<*>) = ap

instance Monad Result where
  -- implement return and >>=
  return = todo
  (>>=) = todo

I am able to clear all tests by only defining the Monad instance functions, while leaving the Functor instance fmap definition as todo. Even though the definition can be copied from Set 12 (as stated in the exercise) or just defined as fmap = liftM, I would guess the intention is to not let students leave todos in the code.

Exercise 5 could use different names

Do let me know if this is too much or I understood this wrong but I remember when people got offended in the walking dead finale about the same words "eeny" "meeny".

Lecture 3 Quiz

In lecture 3, the question:

What is the type of `const const`?

a. unspecified
b. (c -> a -> b) -> a
c. c -> (a -> b -> a)
d. a -> b -> c -> a

I think only c) is correct but b) c) and d) are all marked as correct.

Three different versions of GHCi found in interactive `stack ghci`

grep -rn -A 1 '$ stack ghci' part1.html
part1.html:293:<pre><code>$ stack ghci
part1.html-294-GHCi, version 8.0.1: http://www.haskell.org/ghc/  :? for help
--
part1.html:891:<pre><code>$ stack ghci
part1.html-892-GHCi, version 8.2.2: http://www.haskell.org/ghc/  :? for help
--
part1.html:1122:<pre><code>$ stack ghci Set1.hs
part1.html-1123-GHCi, version 8.6.5: http://www.haskell.org/ghc/  :? for help

Move "hints" to the bottom of the exercise file

Right now hints are attached to the exercise description so NOT reading them is really hard. They often gave me too much help and spoiled the fun of inventing the solution. I suggest to move them to the bottom of the exercise file so the students will "stop and think" before looking at hint.

Set2a Ex2: test for "takeFinal" is incomplete

Both the test and module solution for Set2a, Ex2 takeFinal don't take the case mentioned in exercise instructions

If the list is shorter than n, return all elements.

into consideration

Exercise instructions:

-- Ex 2: define the function takeFinal, which returns the n last
-- elements of the given list.
--
-- If the list is shorter than n, return all elements.
--
-- Hint! remember the take and drop functions.
takeFinal :: Int -> [a] -> [a]
takeFinal n xs = todo

Tests (here k is always smaller than the length of list):

ex2_takeFinal_1 = property $ do
n <- choose (0,20)
k <- choose (0,n)
return $ $(testing [|takeFinal k [0..n]|]) (?== [n-k+1..n])
ex2_takeFinal_2 = property $ do
n <- choose (0,20)
k <- choose (0,n)
let inp = reverse [0..n]
return $ $(testing [|takeFinal k inp|]) (?== reverse [0..k-1])

And the corresponding module solution (https://haskell.mooc.fi/model/Set2a.hs):

takeFinal :: Int -> [a] -> [a]
takeFinal n xs = drop (length xs - n) xs

stack build failed

When I launch stack build on Ubuntu 20.04 LTS I get the following error:

Downloading lts-18.18 build plan ...
RedownloadInvalidResponse Request {
  host                 = "raw.githubusercontent.com"
  port                 = 443
  secure               = True
  requestHeaders       = []
  path                 = "/fpco/lts-haskell/master//lts-18.18.yaml"
  queryString          = ""
  method               = "GET"
  proxy                = Nothing
  rawBody              = False
  redirectCount        = 10
  responseTimeout      = ResponseTimeoutDefault
  requestVersion       = HTTP/1.1
}

Name collision (mapMaybe) in the Set3a exercise

When I did the last exercise (interpreter) I found it interesting to use Data.Maybe.mapMaybe. Unfortunately in the same file, in the 2nd exercise, there is a function with the same name but a different type. It took me a long time to debug type errors and resolve the collision so I suggest renaming the function or changing the exercise so the type of mapMaybe is correct.

------------------------------------------------------------------------------
-- Ex 2: implement the function mapMaybe that takes a function and a
-- Maybe value. If the value is Nothing, it returns Nothing. If it is
-- a Just, it updates the contained value using the function.
--
-- Examples:
--   mapMaybe length Nothing      ==> Nothing
--   mapMaybe length (Just "abc") ==> Just 3

mapMaybe :: (a -> b) -> Maybe a -> Maybe b
mapMaybe _ Nothing = Nothing
mapMaybe f (Just x) = Just (f x)

------------------------------------------------------------------------------
-- Ex 14: in this exercise you get to implement an interpreter for a
-- simple language. You should keep track of the x and y coordinates,
-- and interpret the following commands:

interpreter :: [String] -> [String]
interpreter cmds = Data.Maybe.mapMaybe printCoordinate (withCoordinates cmds)

printCoordinate :: (String, (Int, Int)) -> Maybe String
printCoordinate (cmd, (x,y)) = case cmd of
  "printX" -> Just (show x)
  "printY" -> Just (show y)
  "printXY" -> Just (show x ++ "," ++ show y)
  _ -> Nothing

withCoordinates :: [String] -> [(String, (Int, Int))]
withCoordinates cmds = zip cmds (scanl move (0,0) cmds)

move :: (Int, Int) -> String -> (Int, Int)
move (x,y) cmd = case cmd of
  "up"    -> (x,y+1)
  "down"  -> (x,y-1)
  "right" -> (x+1,y)
  "left"  -> (x-1,y)
  _       -> (x,y)

Data.Traversable forbidden on haskell.mooc.fi yet not forbidden in haskell-mooc/exercises/Set11aTest.hs

Description: See title
Expected behaviour: Server and git repository agree on the legality of imports
Actual behaviour: Server disallows forM/mapM/Data.Traversable, while Set11aTest.hs in the repository allows it.
Replication:
1. Attempt to use forM or mapM in Set11a.hs
2. Run stack runhaskell Set11aTest.hs, noting the fact it passes without issue.
3. Try to submit it on haskell.mooc.fi
4. Disintegrate as your tests fail

Related text wall:
image

Minor typo in Part2 material about HTTP servers

https://haskell.mooc.fi/part2#writing-a-http-server-wai-and-warp

The code block has a minor error that is already fixed in the HelloServer.hs file. In the file, the function server is correctly called application instead, which main supplies to run.

main = run port application

-- type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
server :: Application
server request respond =
  respond (responseLBS status200 [] (LB.pack "Hello World!"))```

Add test for Set7 ex.3

It would be nice to add a test like bake [Mix, Mix] ==> Error to check for the pattern step Error _ = Error

Exercise 8.3 ambiguous definition

Set8.hs/ Ex 3.

-- Ex 3: implement a rectangle. The value of `rectangle x0 y0 w h`
-- should be a rectangle with the upper left corner at (x0, y0), a
-- width of w, and a height of h.
--
-- Example:
--  renderList (fill white (rectangle 1 2 4 3)) (0,5) (0,5)
--   ==> [["000000","000000","000000","000000","000000","000000"],
--        ["000000","000000","000000","000000","000000","000000"],
--        ["000000","ffffff","ffffff","ffffff","ffffff","000000"],
--        ["000000","ffffff","ffffff","ffffff","ffffff","000000"],
--        ["000000","ffffff","ffffff","ffffff","ffffff","000000"],
--        ["000000","000000","000000","000000","000000","000000"]]

The solution, shown below, accepts coordinates on the x0 and y0 lines (>=), i.e. the top and the left sides of the rectangle, but doesn't accept coordinates on the far sides of the rectangle (<).

There's no way for a student to know this other than by frustrating trial and error. Please update the problem description to state this requirement clearly.

rectangle :: Int -> Int -> Int -> Int -> Shape
rectangle x0 y0 w h = Shape f
  where
    f (Coord x y) = x >= x0 && x < (x0 + w) && y >= y0 && y < (y0 + h)

Update the packages to modern Haskell

Set14a.hs is really problematic. The exercise tells you to consult the documentation, which offers functions like isValidUtf8 and decodeUtf8Lenient. But if you try to use them you see the packages MOOC uses are years out of date.

So now it's not only about trying to learn Haskell, but also figuring out which versions of which functions of which package MOOC supports. Highly frustrating and unnecessarily time consuming.

Please update the exercises and tests to the latest version of Haskell. I tried to do it myself to make a pull request, but couldn't figure out how to fix the build.

Lecture 13 - Example function does not do the expected

In 13.1, (?>) is introduced. This is then used to make the function increase look better. However, this new version of the function is not correct. The current and new value comparison is flipped, i.e. x < val instead of the expected val < x from the original example.

The full block of code where the issue is present for further clarity:

increase :: Eq a => a -> Int -> [(a,Int)] -> Maybe [(a,Int)]
increase key val assocs =
    lookup key assocs ?>
    check ?>
    buildResult
  where check x
           | x < val   = Nothing
           | otherwise = Just x
        buildResult x = Just ((key,val) : delete (key,x) assocs)

Sync hackage doc links with package versions in lts-16.31

Commit 5a8da03 updated LTS from 14.9 to 16.31. In lts-16.31,

  • base has upgraded from 4.12.0.0 to 4.13.0.0
  • containers has upgraded from 0.6.0.1 to 0.6.2.1

Hence the corresponding hackage doc links need an update as well.

There are now 8 such links:

# using gnu-grep
$ grep -rno -P 'https?://hackage\.haskell\.org/package/[a-zA-Z]+\-.*?\.html' *.html
part1.html:2038:http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html
part1.html:2042:http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.List.html
part1.html:2629:https://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-Map-Lazy.html
part1.html:3302:https://hackage.haskell.org/package/base-4.12.0.0/docs/Prelude.html
part1.html:3322:https://hackage.haskell.org/package/base-4.12.0.0/docs/Prelude.html
part1.html:3613:https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-List-NonEmpty.html
part2.html:1629:https://hackage.haskell.org/package/base-4.12.0.0/docs/Prelude.html
part2.html:1629:https://hackage.haskell.org/package/base-4.12.0.0/docs/System-IO.html

Set4b Ex4: typo, repeated "with"

Position:

-- Ex 4: implement concat with with a fold. Define concatHelper and

Proposal:

diff --git a/exercises/Set4b.hs b/exercises/Set4b.hs
index 3091180..5e42e73 100644
--- a/exercises/Set4b.hs
+++ b/exercises/Set4b.hs
@@ -56,7 +56,7 @@ slStart = todo
 slHelper = todo

 ------------------------------------------------------------------------------
--- Ex 4: implement concat with with a fold. Define concatHelper and
+-- Ex 4: implement concat with a fold. Define concatHelper and
 -- concatStart so that the given definition of myConcat joins inner lists
 -- of a list.
 --

Clarify tail recursion in 3.8.5

In chapter 3.8.5. I think it would be helpful to write

This is sumNumbers from earlier in this lecture, which is not tail recursive:

instead of

This is sumNumbers from earlier in this lecture:

zlib missing dependencies

I got the following error during stack build on Ubuntu 20.04:

vector              > Installing library in /home/azureuser/.stack/snapshots/x86_64-linux-tinfo6/caeca5c6bad37a162635b8c749d6ceeed6f84a09afb9a14bd0bc5d201afefed2/8.10.7/lib/x86_64-linux-ghc-8.10.7/vector-0.12.3.1-2QhxFayEJrmJ3PNYTgAmQ3
vector              > Registering library for vector-0.12.3.1..
Progress 65/71        

--  While building package zlib-0.6.2.3 (scroll up to its section to see the error) using:
      /home/user/.stack/setup-exe-cache/x86_64-linux-tinfo6/Cabal-simple_mPHDZzAJ_3.2.1.0_ghc-8.10.7 --builddir=.stack-work/dist/x86_64-linux-tinfo6/Cabal-3.2.1.0 configure --with-ghc=/home/user/.stack/programs/x86_64-linux/ghc-tinfo6-8.10.7/bin/ghc-8.10.7 --with-ghc-pkg=/home/user/.stack/programs/x86_64-linux/ghc-tinfo6-8.10.7/bin/ghc-pkg-8.10.7 --user --package-db=clear --package-db=global --package-db=/home/user/.stack/snapshots/x86_64-linux-tinfo6/caeca5c6bad37a162635b8c749d6ceeed6f84a09afb9a14bd0bc5d201afefed2/8.10.7/pkgdb --libdir=/home/user/.stack/snapshots/x86_64-linux-tinfo6/caeca5c6bad37a162635b8c749d6ceeed6f84a09afb9a14bd0bc5d201afefed2/8.10.7/lib --bindir=/home/user/.stack/snapshots/x86_64-linux-tinfo6/caeca5c6bad37a162635b8c749d6ceeed6f84a09afb9a14bd0bc5d201afefed2/8.10.7/bin --datadir=/home/user/.stack/snapshots/x86_64-linux-tinfo6/caeca5c6bad37a162635b8c749d6ceeed6f84a09afb9a14bd0bc5d201afefed2/8.10.7/share --libexecdir=/home/user/.stack/snapshots/x86_64-linux-tinfo6/caeca5c6bad37a162635b8c749d6ceeed6f84a09afb9a14bd0bc5d201afefed2/8.10.7/libexec --sysconfdir=/home/user/.stack/snapshots/x86_64-linux-tinfo6/caeca5c6bad37a162635b8c749d6ceeed6f84a09afb9a14bd0bc5d201afefed2/8.10.7/etc --docdir=/home/user/.stack/snapshots/x86_64-linux-tinfo6/caeca5c6bad37a162635b8c749d6ceeed6f84a09afb9a14bd0bc5d201afefed2/8.10.7/doc/zlib-0.6.2.3 --htmldir=/home/user/.stack/snapshots/x86_64-linux-tinfo6/caeca5c6bad37a162635b8c749d6ceeed6f84a09afb9a14bd0bc5d201afefed2/8.10.7/doc/zlib-0.6.2.3 --haddockdir=/home/user/.stack/snapshots/x86_64-linux-tinfo6/caeca5c6bad37a162635b8c749d6ceeed6f84a09afb9a14bd0bc5d201afefed2/8.10.7/doc/zlib-0.6.2.3 --dependency=base=base-4.14.3.0 --dependency=bytestring=bytestring-0.10.12.0 -f-bundled-c-zlib -f-non-blocking-ffi -f-pkg-config --exact-configuration --ghc-option=-fhide-source-paths
    Process exited with code: ExitFailure 1

and I had to install some dependencies to fix it:

sudo apt install libghc-zlib-dev libghc-zlib-bindings-dev

Composing permutations in Set 9a

Hey, I'm not an expert on this and it is possible I'm wrong but I think there is an issue with the tests in Chapter 9a. My compose function seems to pass any tests related to it and my permute function fails only when checked together with compose (although there aren't many automated tests but I tested with the examples given in comments).

According to http://www.efgh.com/math/algebra/permutations.htm the composition of two permutations is the same as the composition of two functions.

(f . g)(x) = f(g(x))
(g is applied first and then f)

Composing permutations should follow the same rule?
permute (p `compose` q) xs = permute p (permute q xs)
(apply q first, then p)

However, the explanation in Set9a.hs and the tests in Set9aTest.hs seem to test that
permute (p `compose` q) xs = permute q (permute p xs)

*** Failed! Falsified (after 2 tests):
permute (compose p q) xs == permute q (permute p xs) failed:
  p was [(0,0),(1,3),(2,2),(3,1),(4,4)]
  q was [(0,1),(1,4),(2,0),(3,3),(4,2)], and
  xs was "cdbae";
  permute (compose p q) xs evaluated to "daceb",
  while permute q (permute p xs) evaluated to "aecdb"

I tried to translate the composition example from the website to Haskell like this

-- "Hence {1,3,2} ◌ {2,1,3} = {2,3,1}."
p1 = [(0, 0), (1, 2), (2, 1)] :: Permutation -- using {0, 2, 1} instead of {1, 3, 2}
p2 = [(0, 1), (1, 0), (2, 2)] :: Permutation -- {1, 0, 2} instead of {2, 1, 3}

c1 = p1 `compose` p2 -- => [(0,1),(1,2),(2,0)] -- {1, 2, 0} or with one added to each index {2, 3, 1}

-- "Similarly, it can be shown that {2,1,3} ◌ {1,3,2} = {3,1,2}"
c2 = p2 `compose` p1 -- => [(0,2),(1,0),(2,1)]

-- testing
str = "abc"
ex1 = permute c str
ex1' = permute p1 (permute p2 str) -- p2 applied first
result = ex1 == ex1' -- => True

Exercise Set 8, question 3 ( implement a rectangle) - the given coordinate is the bottom-left one, not upper-left

As the title says. The question would make sense if it were the traditional graphics coordinate system (where the top-left of the screen is (0, 0) and the axes increase top-down and left-right), but since that is not mentioned, in the normal Euclidean coordinate system, the test passes if we consider the given coordinate for the rectangle as the bottom-left, and not the upper-left.

Also, the coordinates appear to be inclusive for the starting corner, but exclusive for the opposite corner.

Am I missing something, or is this really a typo?

Lecture 10 Quiz

What's wrong

In lecture 10, the question

Which of these values is not in weak head normal form?

1. map
2. f 1 : map f (2 : [])
3. Just (not False)
4. (\x -> x) True

does not have an answer attached to it (unable to click)

Suggested Fix

Add a :active css class onto the <li> elements

Set1.hs Ex 4 Description suggestion

Hello, a small suggestion for the description of ex4 on Set 1.

In short: I would propose matching the order arguments are written for both the test file and exercise description

The test file looks for the coordinate arguments in the following order

distance x1 x2 y1 y2 = ....

but it is described as "type Double: x1, y1, x2, and y2" in the Exercise description.

I modelled my answer based off the args ordered in the description and was wondering for a little while why it kept failing the test.

Rendering problem on iPadOS

Browser: Safari on iPadOS 14.0

Expected: text in code blocks is visible

What actually happens: text in code blocks is initially invisible. Switching to another browser tab and back makes the currently on-screen code blocks visible, but not any code blocks outside the current viewport.

Demonstration:

EA54DB80-89F2-4CA6-8B3D-3D95FE6C73DE

Set4a.hs gives import errors when :loading into GHCI

Set4a.hs imports Data.Map and Data.Array which need packages containers and array to be installed. I don't know if the project knows to install them but for some reason they're "hidden" for stack ghci or what exactly is happening but I think there should be atleast a comment in the Set4a.hs file about the potential errors and how to fix them...

Fixing it was easy enough by reading the error messages but my editor integration is still broken for that file and I don't know how I would tell my editor's plugin or Haskell Language Server to "see" those "hidden packages".

Included is what happens on my system after cloning the repository and trying to :load the Set4a.hs file into GHCI.

Sorry if it's confusing, new to Haskell and the whole ecosystem.

error.txt

Set14b.hs import error when :loading in GHCI

Similar to here, #14

Easily avoided by using stack ghci Set14b.hs instead but should probably be fixed. Missing package from the cabal file seems to be "http-types"

Configuring GHCi with the following packages: tests
GHCi, version 8.10.4: https://www.haskell.org/ghc/  :? for help
macro 'doc' overwrites builtin command.  Use ':def!' to overwrite.
Loaded GHCi configuration from /home/sose/.ghci
Loaded GHCi configuration from /tmp/haskell-stack-ghci/2a3bbd58/ghci-script
λ> :l Set14b
[1 of 2] Compiling Mooc.Todo        ( /home/sose/koodi/haskell/mooc2/haskell-mooc/exercises/Mooc/Todo.hs, interpreted )
[2 of 2] Compiling Set14b           ( Set14b.hs, interpreted )

Set14b.hs:26:1: error:
    Could not load module ‘Network.HTTP.Types’
    It is a member of the hidden package ‘http-types-0.12.3’.
    You can run ‘:set -package http-types’ to expose it.
    (Note: this unloads all the modules in the current scope.)
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
   |
26 | import Network.HTTP.Types (status200)
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, one module loaded.
λ> 
Leaving GHCi.
~/.../haskell-mooc/exercises >>> stack ghci Set14b.hs                                         ±[●●][master]

Warning: Couldn't find a component for file target /home/sose/koodi/haskell/mooc2/haskell-mooc/exercises/Set14b.hs. This means that the correct ghc options might not be used.
         Attempting to load the file anyway.
Configuring GHCi with the following packages: 
GHCi, version 8.10.4: https://www.haskell.org/ghc/  :? for help
macro 'doc' overwrites builtin command.  Use ':def!' to overwrite.
Loaded GHCi configuration from /home/sose/.ghci
[1 of 2] Compiling Mooc.Todo        ( Mooc/Todo.hs, interpreted )
[2 of 2] Compiling Set14b           ( /home/sose/koodi/haskell/mooc2/haskell-mooc/exercises/Set14b.hs, interpreted )
Ok, two modules loaded.
Loaded GHCi configuration from /tmp/haskell-stack-ghci/68be6ace/ghci-script
λ> 

Set1Test.hs validation not working?

Resolved: my type did not match the expected answer in the marking code.


Hello,

I've completed Set1 and am 100% certain that my code works but I keep getting the following error messages. What can I do?

`*Set1> :q
Leaving GHCi.
PS ...\haskell-mooc-master\exercises> stack runhaskell Set1Test.hs

Set1Test.hs:52:63: error:
* Couldn't match type Char' with [Char]'
Expected type: [String]
Actual type: [Char]
* In the second argument of (?==)', namely "eeny"'
In the first argument of \ k_aabR -> (counterexample ("eeny" ++ (" " ++ (intercalate " ") (show' (2 * x) : [])))) ((within timeLimit) (k_aabR (eeny (2 * x))))', namely (?== "eeny")'
In the expression:
(\ k_aabR
-> (counterexample
("eeny" ++ (" " ++ (intercalate " ") (show' (2 * x) : []))))
((within timeLimit) (k_aabR (eeny (2 * x)))))
(?== "eeny")
|
52 | ex5_eeny_even = forAll_ $ \x -> $(testing [|eeny (2*x)|]) (?=="eeny")
| ^^^^^^

Set1Test.hs:53:65: error:
* Couldn't match type Char' with [Char]'
Expected type: [String]
Actual type: [Char]
* In the second argument of (?==)', namely "meeny"'
In the first argument of \ k_aaco -> (counterexample ("eeny" ++ (" " ++ (intercalate " ") (show' ((2 * x) + 1) : [])))) ((within timeLimit) (k_aaco (eeny ((2 * x) + 1))))', namely (?== "meeny")'
In the expression:
(\ k_aaco
-> (counterexample
("eeny" ++ (" " ++ (intercalate " ") (show' ((2 * x) + 1) : []))))
((within timeLimit) (k_aaco (eeny ((2 * x) + 1)))))
(?== "meeny")
|
53 | ex5_meeny_odd = forAll_ $ \x -> $(testing [|eeny (2*x+1)|]) (?=="meeny")
| ^^^^^^^

Set1Test.hs:86:38: error:
* Couldn't match expected type Int' with actual type Integer'
* In the first argument of isZero', namely n'
In the first argument of k_aaeu', namely (isZero n)'
In the second argument of within', namely (k_aaeu (isZero n))'
|
86 | ex8_isZero_positive (Positive n) = $(testing [|isZero n|]) (?== False)
| ^^^^^^^^^^^^^^^^^^^^

Set1Test.hs:89:38: error:
* Couldn't match expected type Int' with actual type Integer'
* In the first argument of isZero', namely n'
In the first argument of k_aaeJ', namely (isZero n)'
In the second argument of within', namely (k_aaeJ (isZero n))'
|
89 | ex8_isZero_negative (Positive n) = $(testing [|isZero n|]) (?== False)`

Thanks,

tobz

Ex 6 of Set4a.hs

-- Examples:
--   incrementKey True [(True,1),(False,3),(True,4)] ==> [(True,2),(False,3),(True,5)]

I think [(True,2),(True,5)] is correct.

Potential rework of part 2.1 to reduce reliance on knowledge of other programming languages

Below is a suggested rework of part 2.1 to reduce the requirement of knowledge about Java, Python or other imperative programming languages and to focus instead on how Haskell would resolve the tail and non-recursive variations of a function.

I haven't raised this as a PR because trying to match the markup in the correct form looked like a nightmare and I presume you're using some program to generate the HTML anyway so it would probably also be less useful to you in that form.

I've retained some references to tail recursion allowing the generation of loops in machine code and being equivalent to loops in other languages but just reduced the prominence of that.

Please feel free to use this in whole or in part if you find any of it useful.


2.1 Recursion and Helper Functions

You saw in the previous chapter that you can create a factorial function:

factorial :: Int -> Int
factorial 1 = 1
factorial n = n * factorial (n-1)

Unfortunately, the above function isn't as efficient as it could be because Haskell has to resolve each part in multiple steps. These are the steps it goes through in order to do that:

factorial 5 = 5 * (factorial 4)
            = 5 * (4 * (factorial 3))
            = 5 * (4 * (3 * (factorial 2)))
            = 5 * (4 * (3 * (2 * (factorial 1))))
            = 5 * (4 * (3 * (2 * 1))))
            = 5 * (4 * (3 * 2)))
            = 5 * (4 * 6))
            = 5 * 24
            = 120

As you can see, Haskell has to retain a huge amount of state as it works through this calculation. This is absolutely fine if n is small but if n becomes large, it becomes increasingly inefficient and consumes lots of memory.

Were you to run print $ factorial 300000000, you could watch your task manager in horror as your simple program consumes several gigabytes of RAM!

Thankfully, you can write factorial in a slightly different way by storing the running total as you go along. Let's call this function factorial2 for now.

factorial2 :: Int -> Int -> Int
factorial2 1 total = total
factorial2 n total = factorial2 (n-1) (total * n)

Let's take a look at how this gets evaluated:

factorial2 5 1 = factorial2 4 (1 * 5)
               = factorial2 3 (5 * 4)
               = factorial2 2 (20 * 3)
               = factorial2 1 (60 * 2)
               = 120

In this version, the amount of work Haskell has to do to get to the answer is dramatically reduced and the amount of working state it needs to keep as it goes along is reduced even further.

This type of recursion where a function just directly calls itself with different arguments is called tail recursion. Tail recursion corresponds to loops in other programming languages. This is why tail recursion is often fast: the compiler can generate a loop in machine code when it sees tail recursion.

You still have one problem remaining at this point though, this new factorial function is much harder to use than the original, you have to remember each and every time you want to use it that you want to use it that you must call it with an extra argument of 1, e.g. factorial2 n 1. If you make a mistake and accidentally pass a number other than 1, you won't get the right answer.

There is a solution for this too and the answer is helper functions!

Let's rename the factorial2 function as factorialHelper.

factorialHelper :: Int -> Int -> Int
factorialHelper 1 total = total
factorialHelper n total = factorialHelper (n-1) (total * n)

You can then simply write a second function factorial which always calls factorialHelper with the requisite second argument of 1.

factorial :: Int -> Int
factorial n = factorialHelper n 1

Finally, with a bit of work, you've got a version that has both great performance and is easy and well-behaved to work with.

You could be forgiven for thinking at this point that recursion is only useful for maths equations but it's actually very handy for so-called utility functions as well.

Suppose that you wish to write a function that repeats a particular String n times, you can use a recursive function to facilitate this.

repeatString n str = repeatHelper n str ""

repeatHelper 0 _   result = result
repeatHelper n str result = repeatHelper (n-1) str (result++str)

repeatString 5 "ABC" would give the answer "ABCABCABCABCABC".

This is another example of a tail recursive function and something that you might expect to be a loop in a programming language like Java or Python.

Here is another example for computing Fibonacci numbers efficiently:

-- fibonacci numbers, fast version
fibonacci :: Integer -> Integer
fibonacci n = fibonacci' 0 1 n

fibonacci' :: Integer -> Integer -> Integer -> Integer
fibonacci' a b 1 = b
fibonacci' a b n = fibonacci' b (a+b) (n-1)

Sidenote: Haskell programs often use the apostrophe to name helper functions and alternative versions of functions. Thus the name fibonacci' for the helper function above. Names like foo' are usually read foo prime (like in mathematics).

I said earlier that this version of fibonacci is more efficient. Can you see why? The answer is that there are less recursive calls. The expression fibonacci' _ _ n calls fibonacci' _ _ (n-1) once, and this means that we can compute fibonacci' _ _ n in n steps.

Submission fails with factory code

Set13b has the following:

-- Write a log message
msgSL :: String -> SL ()
msgSL msg = SL ((),,[msg])

When submitted, this fails with "Illegal tuple section" error.

Exercise set: Set13b.hs

Submission time: 2023-12-01 04:08:30

Submission status: READY

Error report:

Set13b.hs:337:16: error: Illegal tuple section: use TupleSections
    |
337 | msgSL msg = SL ((),,[msg])
    |                ^^^^^^^^^^^

Set13b.hs:365:17: error: Illegal tuple section: use TupleSections
    |
365 |   return a = SL (a,,[])
    |                 ^^^^^^^

The second error comes from the code I wrote, but the first error is due to OOTB code.

This can be easily fixed by adding {-# LANGUAGE TupleSections #-} at the top of the file, but there is a clear disconnect between the code and the assessment server.

Lec 4.7: last paragraph not parsed to an html list

The (source of the) last paragraph in lecture 4.7 Reading Docs contains an unordered list, but it is not parsed to be an html list.

<p>In summary, here are the main ways of reading Haskell library documentation: - If you know the name of the package you browse the docs via <a href="https://hackage.haskell.org/" class="uri">https://hackage.haskell.org/</a>. - If you know the name of the function you can find it using <a href="https://hoogle.haskell.org/" class="uri">https://hoogle.haskell.org/</a>. - If you’re using <code>stack</code> you can use <code>stack haddock --open</code> or <code>stack haddock --open &lt;package&gt;</code> to open docs in your browser.</p>

Expected parsing result:

<p>In summary, here are the main ways of reading Haskell library documentation: 
<ul>
  <li>If you know the name of the package you browse the docs via <a href="https://hackage.haskell.org/" class="uri">https://hackage.haskell.org/</a>.</li>
  <li>If you know the name of the function you can find it using <a href="https://hoogle.haskell.org/" class="uri">https://hoogle.haskell.org/</a>.</li>
  <li>If you’re using <code>stack</code> you can use <code>stack haddock --open</code> or <code>stack haddock --open &lt;package&gt;</code> to open docs in your browser.</li>
</ul>
</p>

Encountered an error related to ffi.h while building the project on Apple Silicon macOS Ventura 13.3.1

While attempting to execute the stack build command to build the project on an Apple Silicon macOS system, I encountered the following issue:

primitive           > /private/var/folders/w6/wcmb44552qq33sxlxwhptwqm0000gn/T/stack-6a68bccd28c38a9e/primitive-0.7.3.0//var/folders/w6/wcmb44552qq33sxlxwhptwqm0000gn/T/ghc66884_0/ghc_45.c:4:10: error:
primitive           >      fatal error: 'ffi.h' file not found
primitive           >   |
primitive           > 4 | #include <ffi.h>
primitive           >   |          ^
primitive           > #include <ffi.h>
primitive           >          ^~~~~~~
primitive           > 1 error generated.
primitive           > `gcc' failed in phase `C Compiler'. (Exit code: 1)

The issue of the missing libffi library occurs in multiple places.

Error: [S-7282]
       Stack failed to execute the build plan.
       
       While executing the build plan, Stack encountered the following errors:
       
       [S-7011]
       While building package primitive-0.7.3.0 (scroll up to its section to see the
       error) using:
       /Users/chenjunqi/.stack/setup-exe-cache/aarch64-osx/Cabal-simple_SvXsv1f__3.6.3.0_ghc-9.2.7 --verbose=1 --builddir=.stack-work/dist/aarch64-osx/Cabal-3.6.3.0 build --ghc-options " -fdiagnostics-color=always"
       Process exited with code: ExitFailure 1 
       
       [S-7011]
       While building package old-time-1.1.0.3 (scroll up to its section to see the
       error) using:
       /private/var/folders/w6/wcmb44552qq33sxlxwhptwqm0000gn/T/stack-6a68bccd28c38a9e/old-time-1.1.0.3/.stack-work/dist/aarch64-osx/Cabal-3.6.3.0/setup/setup --verbose=1 --builddir=.stack-work/dist/aarch64-osx/Cabal-3.6.3.0 build --ghc-options " -fdiagnostics-color=always"
       Process exited with code: ExitFailure 1 
       
       [S-7011]
       While building package network-3.1.2.8 (scroll up to its section to see the
       error) using:
       /private/var/folders/w6/wcmb44552qq33sxlxwhptwqm0000gn/T/stack-6a68bccd28c38a9e/network-3.1.2.8/.stack-work/dist/aarch64-osx/Cabal-3.6.3.0/setup/setup --verbose=1 --builddir=.stack-work/dist/aarch64-osx/Cabal-3.6.3.0 build --ghc-options " -fdiagnostics-color=always"
       Process exited with code: ExitFailure 1 
       
       [S-7011]
       While building package hourglass-0.2.12 (scroll up to its section to see the
       error) using:
       /Users/chenjunqi/.stack/setup-exe-cache/aarch64-osx/Cabal-simple_SvXsv1f__3.6.3.0_ghc-9.2.7 --verbose=1 --builddir=.stack-work/dist/aarch64-osx/Cabal-3.6.3.0 build --ghc-options " -fdiagnostics-color=always"
       Process exited with code: ExitFailure 1 
       
       [S-7011]
       While building package basement-0.0.15 (scroll up to its section to see the
       error) using:
       /Users/chenjunqi/.stack/setup-exe-cache/aarch64-osx/Cabal-simple_SvXsv1f__3.6.3.0_ghc-9.2.7 --verbose=1 --builddir=.stack-work/dist/aarch64-osx/Cabal-3.6.3.0 build --ghc-options " -fdiagnostics-color=always"
       Process exited with code: ExitFailure 1 
       
       [S-7011]
       While building package direct-sqlite-2.3.28 (scroll up to its section to see
       the error) using:
       /Users/chenjunqi/.stack/setup-exe-cache/aarch64-osx/Cabal-simple_SvXsv1f__3.6.3.0_ghc-9.2.7 --verbose=1 --builddir=.stack-work/dist/aarch64-osx/Cabal-3.6.3.0 build --ghc-options " -fdiagnostics-color=always"
       Process exited with code: ExitFailure 1 
       
       [S-7011]
       While building package hashable-1.4.2.0 (scroll up to its section to see the
       error) using:
       /Users/chenjunqi/.stack/setup-exe-cache/aarch64-osx/Cabal-simple_SvXsv1f__3.6.3.0_ghc-9.2.7 --verbose=1 --builddir=.stack-work/dist/aarch64-osx/Cabal-3.6.3.0 build --ghc-options " -fdiagnostics-color=always"
       Process exited with code: ExitFailure 1 
       
       [S-7011]
       While building package clock-0.8.3 (scroll up to its section to see the error)
       using:
       /Users/chenjunqi/.stack/setup-exe-cache/aarch64-osx/Cabal-simple_SvXsv1f__3.6.3.0_ghc-9.2.7 --verbose=1 --builddir=.stack-work/dist/aarch64-osx/Cabal-3.6.3.0 build --ghc-options " -fdiagnostics-color=always"
       Process exited with code: ExitFailure 1 

This issue is caused by the missing libffi library. libffi is a cross-platform foreign function interface library used for calling functions compiled to native code.

I have installed libffi on macOS using Homebrew and added the include directory of libffi to the project's stack.yaml file, but I still encountered the same issue. How can I resolve this problem?

Thank you!

Set15 Ex7: Ambiguity with non decimal representation of integers

This is minor "issue" but following implementation for exercise 7

boolOrInt :: String -> Validation (Either Bool Int)
boolOrInt s = isBool s <|> isInt s
  where isInt  = maybe (invalid "Not an Int") (pure . Right) . readMaybe
        isBool = maybe (invalid "Not a Bool") (pure . Left)  . readMaybe

passes tests until string with valid integer in non decimal numeral system such as 0x1 or 0o2 is generated.

Example of failure:

boolOrInt "0x1" 
got:      Ok (Right 1) 
expected: Errors ["Not a Bool","Not an Int"]

Suggestions to help student catch/avoid this edge case

a. add a test case to enforce valid integers to be decimals

b. modify tests to allow non decimal integers

c. instruct students to regard valid integers to be only in decimal form and raise error otherwise in exercise description

Set14b.hs does not load in GHCI

To reproduce:

  • install haskell:
sudo apt install -y build-essential curl libffi-dev libffi8ubuntu1 libgmp-dev libgmp10 libncurses-dev libncurses5 libtinfo5 zlib1g-dev &&
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | BOOTSTRAP_HASKELL_NONINTERACTIVE=1 BOOTSTRAP_HASKELL_GHC_VERSION=latest BOOTSTRAP_HASKELL_CABAL_VERSION=latest BOOTSTRAP_HASKELL_INSTALL_STACK=1 BOOTSTRAP_HASKELL_INSTALL_HLS=1 BOOTSTRAP_HASKELL_ADJUST_BASHRC=P sh
ghci> :load Set14b.hs 
[1 of 2] Compiling Mooc.Todo        ( Mooc/Todo.hs, interpreted )
[2 of 2] Compiling Set14b           ( Set14b.hs, interpreted )

Set14b.hs:24:1: error:
    Could not find module ‘Network.Wai’
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
   |
24 | import Network.Wai (pathInfo, responseLBS, Application)
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Set14b.hs:25:1: error:
    Could not find module ‘Network.Wai.Handler.Warp’
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
   |
25 | import Network.Wai.Handler.Warp (run)
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Set14b.hs:26:1: error:
    Could not find module ‘Network.HTTP.Types’
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
   |
26 | import Network.HTTP.Types (status200)
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Set14b.hs:29:1: error:
    Could not find module ‘Database.SQLite.Simple’
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
   |
29 | import Database.SQLite.Simple (open,execute,execute_,query,query_,Connection,Query(..))
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, one module loaded.

Use links to latest hackage doc pages

Unless the material need to stick to specific version of GHC/haskell package, I think it's preferable to use general links which will redirect to latest version of hackage doc pages.

For example, current link

<a href="http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html#map">Here’s map</a>

suggested link (https used)

<a href="https://hackage.haskell.org/package/base/docs/src/GHC.Base.html#map">Here’s map</a>

which will redirect to doc page for the latest base-4.14.1.0.

6 such links are found in part1.html:

$ grep -rno 'https\?://hackage\.haskell\.org/package/[a-xA-Z]\+-.*\.html' part1.html

part1.html:2024:http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html
part1.html:2028:http://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.List.html
part1.html:2605:https://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-Map-Lazy.html
part1.html:3273:https://hackage.haskell.org/package/base-4.12.0.0/docs/Prelude.html
part1.html:3293:https://hackage.haskell.org/package/base-4.12.0.0/docs/Prelude.html
part1.html:3548:https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-List-NonEmpty.html

HLint to CI/CD

Adding HLint or some other lint to CI/CD would make the .hs files already linted and the user shouldn't have to lint and guess the style themselves.

Stack init failed

I cloned the repository and ran stack init, but the initialization failed.

❯ stack init
Looking for .cabal or package.yaml files to use to init the project.
Using cabal packages:
- exercises/

Selecting the best among 21 snapshots...

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/8.yaml
    ghc-9.0.2 cannot be used for these packages:
        - tests
    base version 4.15.1.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.17.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2022/5/20.yaml
    ghc-9.2.2 cannot be used for these packages:
        - tests
    base version 4.16.1.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.18.0.0 found
        - tests requires ==2.16.0.0

* Partially matches https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/28.yaml
    JuicyPixels version 3.3.7 found
        - tests requires ==3.3.6
    warp version 3.3.20 found
        - tests requires ==3.3.18

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/17/15.yaml
    ghc-8.10.4 cannot be used for these packages:
        - tests
    base version 4.14.1.0 found
        - tests requires ==4.14.3.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/16/31.yaml
    ghc-8.8.4 cannot be used for these packages:
        - tests
    base version 4.13.0.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.15.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/15/16.yaml
    ghc-8.8.3 cannot be used for these packages:
        - tests
    base version 4.13.0.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.15.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/14/27.yaml
    ghc-8.6.5 cannot be used for these packages:
        - tests
    base version 4.12.0.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.14.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/13/30.yaml
    ghc-8.6.5 cannot be used for these packages:
        - tests
    base version 4.12.0.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.14.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/12/26.yaml
    ghc-8.4.4 cannot be used for these packages:
        - tests
    base version 4.11.1.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.13.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/11/22.yaml
    ghc-8.2.2 cannot be used for these packages:
        - tests
    base version 4.10.1.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.12.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/10/10.yaml
    ghc-8.2.2 cannot be used for these packages:
        - tests
    base version 4.10.1.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.12.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/9/21.yaml
    ghc-8.0.2 cannot be used for these packages:
        - tests
    base version 4.9.1.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.11.1.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/8/24.yaml
    ghc-8.0.2 cannot be used for these packages:
        - tests
    base version 4.9.1.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.11.1.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/7/24.yaml
    ghc-8.0.1 cannot be used for these packages:
        - tests
    base version 4.9.0.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.11.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/6/35.yaml
    ghc-7.10.3 cannot be used for these packages:
        - tests
    base version 4.8.2.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.10.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/5/18.yaml
    ghc-7.10.3 cannot be used for these packages:
        - tests
    base version 4.8.2.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.10.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/4/2.yaml
    ghc-7.10.3 cannot be used for these packages:
        - tests
    base version 4.8.2.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.10.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/3/22.yaml
    ghc-7.10.2 cannot be used for these packages:
        - tests
    base version 4.8.1.0 found
        - tests requires ==4.14.3.0
    template-haskell version 2.10.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/2/22.yaml
    ghc-7.8.4 cannot be used for these packages:
        - tests
    base version 4.7.0.2 found
        - tests requires ==4.14.3.0
    template-haskell version 2.9.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/1/15.yaml
    ghc-7.8.4 cannot be used for these packages:
        - tests
    base version 4.7.0.2 found
        - tests requires ==4.14.3.0
    template-haskell version 2.9.0.0 found
        - tests requires ==2.16.0.0

* Rejected https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/0/7.yaml
    ghc-7.8.3 cannot be used for these packages:
        - tests
    base version 4.7.0.1 found
        - tests requires ==4.14.3.0
    template-haskell version 2.9.0.0 found
        - tests requires ==2.16.0.0

Selected resolver: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/28.yaml
Resolver 'https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/28.yaml' does not have all the packages to match your requirements.
    JuicyPixels version 3.3.7 found
        - tests requires ==3.3.6
    warp version 3.3.20 found
        - tests requires ==3.3.18

This may be resolved by:
    - Using '--omit-packages' to exclude mismatching package(s).
    - Using '--resolver' to specify a matching snapshot/resolver

I am using M1 Mac, OS 12.3.1, Stack version 2.7.5. Does anyone know how to fix this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.