diff --git a/README.md b/README.md index 7a12703..0eae721 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,41 @@ -# Fall-2018 - -[website](http://www.cs.bu.edu/fac/snyder/cs320/) [piazza](https://piazza.com/class/jlpaiu7tfht5ro?cid=15) - -The notes and assignments for 320 - -## Forking and Adding tests -We will allow you to share tests with the class. These instructions are a work in progress, please add to them. -### Small changes - 1. Click the pencil in the upper right corner - 1. edit the file - 1. press "Create a new branch for this commit and start a pull request" - 1. click the make pull request button - 1. wait for aproval, you will see your request under "Pull requests" - 1. Someone will merge you commit or comment about why it can't be merged - 1. if there are problems with you commit you will need to follow some of the instructions bellow to fix it - -### Large changes - * Make a fork of the class repo: https://github.com/BU-CS320/Fall-2018 - * clone your fork locally (keep it separate from your assignment clone) - * go to the test directory (in this case Fall-2018/assignments/week2/lab2/tests) - * add a test - * push the test up to your fork - * https://help.github.com/articles/creating-a-pull-request/ - * If your test looks good we will accept it - -Once you have followed the steps for forking a repository all you need to do now is clone the forked repository into your terminal. Then follow these steps: - 1. Need to add the ability to update your forked repository to keep it up to date with the master branch - 1. '''cd'' into your forked repo - 1. type '''git remote add upstream https://github.com/BU-CS320/Fall-2018.git''' - 1. type '''git fetch upstream''' then '''git pull upstream''' to update your forked repository with the master branch - 1. Now just make your edits, whether it be fixing typos, adding test cases, etc. - 1. Once you have made your changes, all you need to is push your changes to your forked repo to save your work. - 1. Pushing your work to the masterbranch - 1. Once you push your changes, go onto github and click the tab pull requests. - 1. Once in this tab, hit the button that says __New pull request__ - 1. Once you get to this page, you will see this at the top ![](ing/gitpullrequest.JPG). This will compare your forked repository with the master branch. - 1. Then click __Create a new pull__ - 1. Add any comment you want - 1. Then click __Create a new pull__ at the bottom of the page ![](ing/push-and-pull.gif) - 1. After this you should have successfully put in the pull request, and now just wait for the person with the access to the master branch to accept the request. +# Fall-2018 + +[website](http://www.cs.bu.edu/fac/snyder/cs320/) [piazza](https://piazza.com/class/jlpaiu7tfht5ro?cid=15) + +The notes and assignments for 320 + +## Forking and Adding tests +We will allow you to share tests with the class. These instructions are a work in progress, please add to them. +### Small changes + 1. Click the pencil in the upper right corner + 1. edit the file + 1. press "Create a new branch for this commit and start a pull request" + 1. click the make pull request button + 1. wait for aproval, you will see your request under "Pull requests" + 1. Someone will merge you commit or comment about why it can't be merged + 1. if there are problems with you commit you will need to follow some of the instructions bellow to fix it + +### Large changes + * Make a fork of the class repo: https://github.com/BU-CS320/Fall-2018 + * clone your fork locally (keep it separate from your assignment clone) + * go to the test directory (in this case Fall-2018/assignments/week2/lab2/tests) + * add a test + * push the test up to your fork + * https://help.github.com/articles/creating-a-pull-request/ + * If your test looks good we will accept it + +Once you have followed the steps for forking a repository all you need to do now is clone the forked repository into your terminal. Then follow these steps: + 1. Need to add the ability to update your forked repository to keep it up to date with the master branch + 1. '''cd'' into your forked repo + 1. type '''git remote add upstream https://github.com/BU-CS320/Fall-2018.git''' + 1. type '''git fetch upstream''' then '''git pull upstream''' to update your forked repository with the master branch + 1. Now just make your edits, whether it be fixing typos, adding test cases, etc. + 1. Once you have made your changes, all you need to is push your changes to your forked repo to save your work. + 1. Pushing your work to the masterbranch + 1. Once you push your changes, go onto github and click the tab pull requests. + 1. Once in this tab, hit the button that says __New pull request__ + 1. Once you get to this page, you will see this at the top ![](ing/gitpullrequest.JPG). This will compare your forked repository with the master branch. + 1. Then click __Create a new pull__ + 1. Add any comment you want + 1. Then click __Create a new pull__ at the bottom of the page ![](ing/push-and-pull.gif) + 1. After this you should have successfully put in the pull request, and now just wait for the person with the access to the master branch to accept the request. diff --git a/assignments/week1/lab1/README.md b/assignments/week1/lab1/README.md index ab7e8b1..71affe6 100644 --- a/assignments/week1/lab1/README.md +++ b/assignments/week1/lab1/README.md @@ -19,10 +19,14 @@ If you are a mac user and you are may need to follow the instructions under [mac * ```cd``` into the newly created directory by typing ```cd week1-username``` with ```username``` replaced with your user name * You always want to take advantage of the latest corrections to the assignments and shared tests so we will add the main repository as a source * In your terminal type ```git remote add upstream https://github.com/BU-CS320/Fall-2018.git``` - * check that it worked by typing ```git remote -v```. You should see see the line ```upstream https://github.com/BU-CS320/Fall-2018.git (fetch)``` + * check that it worked by typing ```git remote -v```. You should see the line ```upstream https://github.com/BU-CS320/Fall-2018.git (fetch)``` * You always want to keep your assignment up to date by running ```git pull upstream master```, do that now * ```cd``` into this assignment (```cd assignments/week1/lab1```), first we will write a greeting +<<<<<<< HEAD + * run ```cabal new-repl``` in the terminal (it is important that you do this in the ```lab1``` directory). You should see +======= * run ```cabal new-repl (or cabal repl if gets "Failed to load interface")``` in the terminal (it is important that you do this in the ```lab1``` directory). You should see +>>>>>>> 2971d6e0044f83cf5c055ea1d6ad2f05fcf6fcf0 ``` Preprocessing library for lab1-0.1.0.0.. GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help @@ -37,7 +41,7 @@ Ok, one module loaded. * Haskell is a functional language so define the identity function by changing ```ident x = undefined``` to ```ident x = x``` * reset the terminal by typing ```:reload``` * Haskell doesn't let us see the definition of functions, but we can test by running ```ident greeting``` and see if we get back the greeting we expect - * type ```:q``` to quit the REPL in the + * type ```:q``` to quit the REPL in the * run the tests by running ```cabal test```, some students need to run ```cabal configure --enable-tests``` first * make a commit by typing ```git commit -a -m "my first commit"``` into the console * submit your work by typing ```git push``` @@ -57,7 +61,7 @@ Complete the survey by adding your answers to [survey.md](survey.md). You may d If you are having ```git``` issues run ```git status``` and call on Mark for help. ## Optional Bonus: Sharing Tests, and correcting my spelling -We will allow you to share tests with the class. To do this +We will allow you to share tests with the class. To do this * Make a fork of the class repo: https://github.com/BU-CS320/Fall-2018 * clone your fork locally (keep it separate from your assignment clone) * go to the test directory (in this case Fall-2018/assignments/week1/lab1/tests) diff --git a/assignments/week10/hw/tests/LangParserTest.hs b/assignments/week10/hw/tests/LangParserTest.hs index e7c11b4..3620ddd 100644 --- a/assignments/week10/hw/tests/LangParserTest.hs +++ b/assignments/week10/hw/tests/LangParserTest.hs @@ -1,75 +1,94 @@ module LangParserTest where -import Test.Tasty (testGroup) -import Test.Tasty.HUnit (assertEqual, assertBool, testCase) -import Test.Tasty.QuickCheck - - -import ParserMonad - -import Lang -import LangParser - - - - ---TODO: move the generator to a shared place - -instance Arbitrary Ast where - arbitrary = sized arbitrarySizedAst --- TODO: implement shrink for better error messages --- see http://hackage.haskell.org/package/QuickCheck-2.12.6.1/docs/Test-QuickCheck-Arbitrary.html#v:shrink - -arbitrarySizedAst :: Int -> Gen Ast -arbitrarySizedAst m | m < 1 = do i <- arbitrary - b <- arbitrary - node <- elements [ValInt i, ValBool b, Nil] - return $ node -arbitrarySizedAst m | otherwise = do l <- arbitrarySizedAst (m `div` 2) - r <- arbitrarySizedAst (m `div` 2) - str <- elements ["x","y","z"] - ifast <- arbitrarySizedIf m - node <- elements [And l r, Or l r, Not l, - Plus l r, Minus l r, Mult l r, Div l r, - Cons l r, - ifast, - Let str l r, - Lam str l, - App l r, - Var str - ] - return node - --- it would be better if every branch were built like this so the balance would be maintained -arbitrarySizedIf :: Int -> Gen Ast -arbitrarySizedIf m = do b <- arbitrarySizedAst (m `div` 3) - t <- arbitrarySizedAst (m `div` 3) - e <- arbitrarySizedAst (m `div` 3) - return $ If b t e - -unitTests = - testGroup - "LangParserTest" - [instructorTests, - -- TODO: your tests here!!! - somemoreTests] - -instructorTests = testGroup - "instructorTests" - [ - testProperty "parse should return the same AST when fully parenthisized" $ ((\ x -> Just (x , "") == (parse parser $ fullyParenthesized x)) :: Ast -> Bool), - testProperty "parse should return the same AST when pretty printed" $ ((\ x -> Just (x , "") == (parse parser $ prettyShow x 0)) :: Ast -> Bool) - ] - - --- TODO: your tests here!!! --- TODO: Many, many more example test cases (every simple thing, many normal things, some extreme things) - -somemoreTests = testGroup - "somemoreTests" - [ - testCase "bool precedence test" $ assertEqual [] (Just((And (Not (ValBool False)) (ValBool True)), "")) $ (parse parser "! false && true"), - testCase "parens and bool precedence test" $ assertEqual [] (Just((Not (And (ValBool False) (ValBool True))), "")) $ (parse parser "! (false && true)"), - testCase "cons right associativity test" $ assertEqual [] (Just (Cons (ValInt 1) (Cons (ValInt 4) (Cons (Plus (ValInt 3) (ValInt 5)) Nil)),"")) $ (parse parser "1 : 4 : 3 + 5"), - testCase "cons different types test" $ assertEqual [] (Just (Cons (ValInt 1) (Cons (ValInt 4) (Cons (ValBool True) Nil)),"")) $ (parse parser "1 : 4 : true") - ] + import Test.Tasty (testGroup) + import Test.Tasty.HUnit (assertEqual, assertBool, testCase) + import Test.Tasty.QuickCheck + + + import ParserMonad + + import Lang + import LangParser + + + + + --TODO: move the generator to a shared place + + instance Arbitrary Ast where + arbitrary = sized arbitrarySizedAst + + arbitrarySizedAst :: Int -> Gen Ast + arbitrarySizedAst m | m < 1 = do i <- arbitrary + b <- arbitrary + node <- elements [ValInt i, ValBool b, Nil] + return $ node + arbitrarySizedAst m | otherwise = do l <- arbitrarySizedAst (m `div` 2) + r <- arbitrarySizedAst (m `div` 2) + str <- elements ["x","y","z"] + ifast <- arbitrarySizedIf m + node <- elements [And l r, Or l r, Not l, + Plus l r, Minus l r, Mult l r, Div l r, + Cons l r, + ifast, + Let str l r, + Lam str l, + App l r, + Var str + ] + return node + + -- it would be better if every branch were built like this so the balance would be maintained + arbitrarySizedIf :: Int -> Gen Ast + arbitrarySizedIf m = do b <- arbitrarySizedAst (m `div` 3) + t <- arbitrarySizedAst (m `div` 3) + e <- arbitrarySizedAst (m `div` 3) + return $ If b t e + + unitTests = + testGroup + "LangParserTest" + [instructorTests + ,somemoreTests + ,myTests + -- TODO: your tests here!!! + ] + + instructorTests = testGroup + "instructorTests" + [ + testProperty "parse should return the same AST when fully parenthisized" $ ((\ x -> Just (x , "") == (parse parser $ fullyParenthesized x)) :: Ast -> Bool), + testProperty "parse should return the same AST when pretty printed" $ ((\ x -> Just (x , "") == (parse parser $ prettyShow x 0)) :: Ast -> Bool) + ] + + somemoreTests = testGroup + "somemoreTests" + [ + testCase "bool precedence test" $ assertEqual [] (Just((And (Not (ValBool False)) (ValBool True)), "")) $ (parse parser "! false && true"), + testCase "parens and bool precedence test" $ assertEqual [] (Just((Not (And (ValBool False) (ValBool True))), "")) $ (parse parser "! (false && true)"), + testCase "cons right associativity test" $ assertEqual [] (Just (Cons (ValInt 1) (Cons (ValInt 4) (Cons (Plus (ValInt 3) (ValInt 5)) Nil)),"")) $ (parse parser "1 : 4 : 3 + 5 : []"), + testCase "cons different types test" $ assertEqual [] (Just (Cons (ValInt 1) (Cons (ValInt 4) (Cons (ValBool True) Nil)),"")) $ (parse parser "1 : 4 : true : []") + ] + + string1 = "let x = 10 in if (\\x -> \\y -> x && y) true false then 0 else let y = 4 in x + y" + ast1 = Let "x" (ValInt 10) (If (App (App (Lam "x" (Lam "y" (And (Var "x") (Var "y")))) (ValBool True)) (ValBool False)) (ValInt 0) (Let "y" (ValInt 4) (Plus (Var "x") (Var "y")))) + string2 = "!false && 3 + 5*4" + ast2 = And (Not (ValBool False)) (Plus (ValInt 3) (Mult (ValInt 5) (ValInt 4))) + string3 = "let z = \\y -> \\x -> y && ! x in if let x = false in x then 10 : 15:[] else z true false" + ast3 = Let "z" (Lam "y" (Lam "x" (And (Var "y") (Not (Var "x"))))) (If (Let "x" (ValBool False) (Var "x")) (Cons (ValInt 10) (Cons (ValInt 15) Nil)) (App (App (Var "z") (ValBool True)) (ValBool False))) + string4 = "10 : true&&false : 1 * 3 : []" + ast4 = Cons (ValInt 10) (Cons (And (ValBool True) (ValBool False)) (Cons (Mult (ValInt 1) (ValInt 3)) Nil)) + string5 = "( (( []) ) )" + ast5 = Nil + + + checkStrings = map (\(str, ast) -> testProperty str $ Just (ast, "") == parse parser str) + + myTests = testGroup + "myTests" + (checkStrings [(string1, ast1), (string2, ast2), (string3, ast3), (string4, ast4), (string5, ast5)]) + + + -- TODO: your tests here!!! + -- TODO: Many, many more example test cases (every simple thing, many normal things, some extreme things) + \ No newline at end of file diff --git a/assignments/week2/hw/src/Hw.hs b/assignments/week2/hw/src/Hw.hs index ec22479..5e72d0b 100644 --- a/assignments/week2/hw/src/Hw.hs +++ b/assignments/week2/hw/src/Hw.hs @@ -1,261 +1,261 @@ -module Hw where -import Prelude(Show, undefined) - --- Data Declarations - "deriving Show" will allow --- data values to be printed by interpreter - -data Bool = True | False deriving Show - -data Nat = Zero | Succ Nat deriving Show - - - -not :: Bool -> Bool -not False = True -not True = False - - -and :: Bool -> Bool -> Bool -and True True = True -and _ _ = False - - -or :: Bool -> Bool -> Bool -or True _ = True -or _ True = True -or _ _ = False - - --- define the following function -xor :: Bool -> Bool -> Bool -xor _ _ = undefined - --- you can also define an "if" construct -cond True x y = x -cond False x y = y - --- basic arithmetic - --- constants are like 0-ary functions (no arguments) --- and must be in lower case - --- the first 5 numbers -zero = Zero -one = (Succ zero) -two = Succ one -three = Succ two -four = Succ three -five = Succ four - - --- the 6 and 9 -six :: Nat -six = undefined - -nine :: Nat -nine = undefined - -add :: Nat -> Nat -> Nat -add x Zero = x -add x (Succ y) = Succ (add x y) - -mult :: Nat -> Nat -> Nat -mult x Zero = Zero -mult x (Succ y) = add x (mult x y) - -exp :: Nat -> Nat -> Nat -exp x Zero = (Succ Zero) -exp x (Succ y) = mult x (exp x y) - --- when are 2 Nats equal? -eq :: Nat -> Nat -> Bool -eq Zero Zero = True -eq (Succ x) (Succ y) = eq x y -eq _ _ = False - --- when are 2 Nats not equal? -ne :: Nat -> Nat -> Bool -ne x y = not (eq x y) - --- the less then function, when is the first argument less then the 2nd -lt :: Nat -> Nat -> Bool -lt Zero (Succ x) = True -lt (Succ x) (Succ y) = lt x y -lt _ _ = False - -le x y = or (lt x y) (eq x y) - -gt x y = lt y x - -ge x y = le y x - --- define the following function - -isEven :: Nat -> Bool -isEven _ = undefined - - ---return the largest of 2 Nats -max :: Nat -> Nat -> Nat -max x y = cond (lt x y) y x - - - --- write a data type for the days of the week -data Weekday -- = ... deriving Show - --- what is your favorite Day? -favoriteDay :: Weekday -favoriteDay = undefined - --- write a function that returns true if it is a weekend -isWeekend :: Weekday -> Bool -isWeekend _ = undefined - --- write a data type for the Months of the year -data Month -- = ... deriving Show - --- what month has your birthday? -partyMonth :: Month -partyMonth = undefined - --- write a function that tells when a month is in the 2018 Fall Semester (see https://www.bu.edu/reg/calendars/) return True if it is -needToDoWork :: Month -> Bool -needToDoWork _ = undefined - - --- write a data type that contains a month, a Nat (representing which week), and a weekday -data Date -- = ... deriving Show - --- when is this homework due? -homworkIsDueOn :: Date -homworkIsDueOn = undefined - --- write a program that returns true on CS 320 lecture dates -lectureDay :: Date -> Bool -lectureDay _ = undefined - - --- write a data type for a 2D point where x and y are Nats -data Point -- = ... deriving Show - --- take in 2 Nats to make your point -makePoint :: Nat -> Nat -> Point -makePoint _ _ = undefined - - --- the Manhattan distance is the distance in the x direction plus the distance in the y direction --- for instance the manhatan distance of points (2,5) and (3,1) is 5 -manhattanDistance :: Point -> Point -> Nat -manhattanDistance _ _ = undefined - - --- assume there is a sad math calss where students can only answer with a Bool OR with a Nat, write a data type for that answer -data SadAnswer -- = ... deriving Show - --- make a Nat answer -answerNat :: Nat -> SadAnswer -answerNat _ = undefined - --- make a Bool answer -answerBool :: Bool -> SadAnswer -answerBool _ = undefined - --- what is 100 - 99? -ans1 :: SadAnswer -ans1 = undefined - --- is 100 - 99 an odd number? -ansTrue :: SadAnswer -ansTrue = undefined - - --- we saw in lab how to write lists for specific data -data ListNat = NilNat | ConsNat Nat ListNat deriving Show - --- write a function that adds everything in the list -sum :: ListNat -> Nat -sum _ = undefined - --- write a function that tells when 2 nat lists are equal -eq_list :: ListNat -> ListNat -> Bool -eq_list _ _ = undefined - --- write a function that tests when a Nat is in a list -member :: Nat -> ListNat -> Bool -member _ _ = undefined - - - --- we also saw how to write general lists -data List a = Nil | Cons a (List a) deriving Show - - --- write a list of all the Bools -listOfBool :: (List Bool) -listOfBool = undefined - --- write a list of the first three Nats -listOfNat :: (List Nat) -listOfNat = undefined - --- write a list of all the week days -listOfWork :: (List Weekday) -listOfWork = undefined - --- functions on lists -length :: (List a) -> Nat -length _ = undefined - - --- in lab we saw that we can return Maybe data when we want to return something but might not -data Maybe x = Nothing | Just x deriving Show - --- functions that returns something if it is the last element of the list and Nothing if the list is empty - -last :: (List a) -> (Maybe a) -last _ = undefined - - -append :: (List a) -> (List a) -> (List a) -append _ _ = undefined - -addToEnd :: (List a) -> a -> (List a) -addToEnd _ _ = undefined - ---reverse a List -rev :: (List a) -> (List a) -rev _ = undefined - - - --- like lists you can constuct a binary tree of Nats - -data TreeNat = NullNat | NodeNat (TreeNat) Nat (TreeNat) deriving Show - -memberTreeNat :: Nat -> TreeNat -> Bool -memberTreeNat _ _ = undefined - -eqTreeNat :: TreeNat -> TreeNat -> Bool -eqTreeNat _ _ = undefined - - --- or a general binary tree - -data Tree a = Null | Node (Tree a) a (Tree a) deriving Show - -size :: (Tree a) -> Nat -size _ = undefined - --- suppose the height is number of nodes in longest path from root to leaf - -height :: (Tree a) -> Nat -height _ = undefined - --- do an inorder traversal -inorder :: (Tree a) -> (List a) -inorder _ = undefined - --- do an preorder traversal -preorder :: (Tree a) -> (List a) -preorder _ = undefined +module Hw where +import Prelude(Show, undefined) + +-- Data Declarations - "deriving Show" will allow +-- data values to be printed by interpreter + +data Bool = True | False deriving Show + +data Nat = Zero | Succ Nat deriving Show + + + +not :: Bool -> Bool +not False = True +not True = False + + +and :: Bool -> Bool -> Bool +and True True = True +and _ _ = False + + +or :: Bool -> Bool -> Bool +or True _ = True +or _ True = True +or _ _ = False + + +-- define the following function +xor :: Bool -> Bool -> Bool +xor _ _ = undefined + +-- you can also define an "if" construct +cond True x y = x +cond False x y = y + +-- basic arithmetic + +-- constants are like 0-ary functions (no arguments) +-- and must be in lower case + +-- the first 5 numbers +zero = Zero +one = (Succ zero) +two = Succ one +three = Succ two +four = Succ three +five = Succ four + + +-- the 6 and 9 +six :: Nat +six = undefined + +nine :: Nat +nine = undefined + +add :: Nat -> Nat -> Nat +add x Zero = x +add x (Succ y) = Succ (add x y) + +mult :: Nat -> Nat -> Nat +mult x Zero = Zero +mult x (Succ y) = add x (mult x y) + +exp :: Nat -> Nat -> Nat +exp x Zero = (Succ Zero) +exp x (Succ y) = mult x (exp x y) + +-- when are 2 Nats equal? +eq :: Nat -> Nat -> Bool +eq Zero Zero = True +eq (Succ x) (Succ y) = eq x y +eq _ _ = False + +-- when are 2 Nats not equal? +ne :: Nat -> Nat -> Bool +ne x y = not (eq x y) + +-- the less then function, when is the first argument less then the 2nd +lt :: Nat -> Nat -> Bool +lt Zero (Succ x) = True +lt (Succ x) (Succ y) = lt x y +lt _ _ = False + +le x y = or (lt x y) (eq x y) + +gt x y = lt y x + +ge x y = le y x + +-- define the following function + +isEven :: Nat -> Bool +isEven _ = undefined + + +--return the largest of 2 Nats +max :: Nat -> Nat -> Nat +max x y = cond (lt x y) y x + + + +-- write a data type for the days of the week +data Weekday -- = ... deriving Show + +-- what is your favorite Day? +favoriteDay :: Weekday +favoriteDay = undefined + +-- write a function that returns true if it is a weekend +isWeekend :: Weekday -> Bool +isWeekend _ = undefined + +-- write a data type for the Months of the year +data Month -- = ... deriving Show + +-- what month has your birthday? +partyMonth :: Month +partyMonth = undefined + +-- write a function that tells when a month is in the 2018 Fall Semester (see https://www.bu.edu/reg/calendars/) return True if it is +needToDoWork :: Month -> Bool +needToDoWork _ = undefined + + +-- write a data type that contains a month, a Nat (representing which week), and a weekday +data Date -- = ... deriving Show + +-- when is this homework due? +homworkIsDueOn :: Date +homworkIsDueOn = undefined + +-- write a program that returns true on CS 320 lecture dates +lectureDay :: Date -> Bool +lectureDay _ = undefined + + +-- write a data type for a 2D point where x and y are Nats +data Point -- = ... deriving Show + +-- take in 2 Nats to make your point +makePoint :: Nat -> Nat -> Point +makePoint _ _ = undefined + + +-- the Manhattan distance is the distance in the x direction plus the distance in the y direction +-- for instance the manhatan distance of points (2,5) and (3,1) is 5 +manhattanDistance :: Point -> Point -> Nat +manhattanDistance _ _ = undefined + + +-- assume there is a sad math calss where students can only answer with a Bool OR with a Nat, write a data type for that answer +data SadAnswer -- = ... deriving Show + +-- make a Nat answer +answerNat :: Nat -> SadAnswer +answerNat _ = undefined + +-- make a Bool answer +answerBool :: Bool -> SadAnswer +answerBool _ = undefined + +-- what is 100 - 99? +ans1 :: SadAnswer +ans1 = undefined + +-- is 100 - 99 an odd number? +ansTrue :: SadAnswer +ansTrue = undefined + + +-- we saw in lab how to write lists for specific data +data ListNat = NilNat | ConsNat Nat ListNat deriving Show + +-- write a function that adds everything in the list +sum :: ListNat -> Nat +sum _ = undefined + +-- write a function that tells when 2 nat lists are equal +eq_list :: ListNat -> ListNat -> Bool +eq_list _ _ = undefined + +-- write a function that tests when a Nat is in a list +member :: Nat -> ListNat -> Bool +member _ _ = undefined + + + +-- we also saw how to write general lists +data List a = Nil | Cons a (List a) deriving Show + + +-- write a list of all the Bools +listOfBool :: (List Bool) +listOfBool = undefined + +-- write a list of the first three Nats +listOfNat :: (List Nat) +listOfNat = undefined + +-- write a list of all the week days +listOfWork :: (List Weekday) +listOfWork = undefined + +-- functions on lists +length :: (List a) -> Nat +length _ = undefined + + +-- in lab we saw that we can return Maybe data when we want to return something but might not +data Maybe x = Nothing | Just x deriving Show + +-- functions that returns something if it is the last element of the list and Nothing if the list is empty + +last :: (List a) -> (Maybe a) +last _ = undefined + + +append :: (List a) -> (List a) -> (List a) +append _ _ = undefined + +addToEnd :: (List a) -> a -> (List a) +addToEnd _ _ = undefined + +--reverse a List +rev :: (List a) -> (List a) +rev _ = undefined + + + +-- like lists you can constuct a binary tree of Nats + +data TreeNat = NullNat | NodeNat (TreeNat) Nat (TreeNat) deriving Show + +memberTreeNat :: Nat -> TreeNat -> Bool +memberTreeNat _ _ = undefined + +eqTreeNat :: TreeNat -> TreeNat -> Bool +eqTreeNat _ _ = undefined + + +-- or a general binary tree + +data Tree a = Null | Node (Tree a) a (Tree a) deriving Show + +size :: (Tree a) -> Nat +size _ = undefined + +-- suppose the height is number of nodes in longest path from root to leaf + +height :: (Tree a) -> Nat +height _ = undefined + +-- do an inorder traversal +inorder :: (Tree a) -> (List a) +inorder _ = undefined + +-- do an preorder traversal +preorder :: (Tree a) -> (List a) +preorder _ = undefined diff --git a/assignments/week3/hw/src/DataProblems.hs b/assignments/week3/hw/src/DataProblems.hs index c9a3b19..ee87c7a 100644 --- a/assignments/week3/hw/src/DataProblems.hs +++ b/assignments/week3/hw/src/DataProblems.hs @@ -1,27 +1,27 @@ -module DataProblems where - --- Define a datatype for deserts: deserts consist of cake, cookies, and icecream. Cookies have a number (how many?), Icecream can be flavored like anything (a string), and cake must be flavored like a desert. - -data Deserts -- = ... deriving Show - -favorite :: Deserts -favorite = undefined - -dontLike :: Deserts -dontLike = undefined - - -willILikeIt :: Deserts -> Bool -willILikeIt = undefined - - --- Define a datatype for a student at BU. Students should have a first name, a last name, a BU ID, a major, and a class year (Freshman, etc.). Names and the BU ID should be Strings, and the others should be represented by other datatypes (you can pick five majors as examples).

- -data Student -- deriving Show - -me :: Student -me = undefined - --- Make a student from a first name, a last name, a BU ID, and a class year. This functions should just return "CS" majors. -mkStudent :: String -> String -> String -> Integer -> Maybe Student -mkStudent = undefined +module DataProblems where + +-- Define a datatype for deserts: deserts consist of cake, cookies, and icecream. Cookies have a number (how many?), Icecream can be flavored like anything (a string), and cake must be flavored like a desert. + +data Deserts -- = ... deriving Show + +favorite :: Deserts +favorite = undefined + +dontLike :: Deserts +dontLike = undefined + + +willILikeIt :: Deserts -> Bool +willILikeIt = undefined + + +-- Define a datatype for a student at BU. Students should have a first name, a last name, a BU ID, a major, and a class year (Freshman, etc.). Names and the BU ID should be Strings, and the others should be represented by other datatypes (you can pick five majors as examples).

+ +data Student -- deriving Show + +me :: Student +me = undefined + +-- Make a student from a first name, a last name, a BU ID, and a class year. This functions should just return "CS" majors. +mkStudent :: String -> String -> String -> Integer -> Maybe Student +mkStudent = undefined diff --git a/assignments/week3/hw/src/Outside.hs b/assignments/week3/hw/src/Outside.hs index bb765fc..bb8c0b7 100644 --- a/assignments/week3/hw/src/Outside.hs +++ b/assignments/week3/hw/src/Outside.hs @@ -1,20 +1,20 @@ -module Outside where -import Set -import BinarySearchTrees - --- Set of 2,4,8,16,32,64 -exampleSet :: Set -exampleSet = undefined - --- when are 2 sets equal? -eqSet :: Set -> Set -> Bool -eqSet _ _ = undefined - - --- Tree of 2,4,8,16,32,64 -exampleBst :: Tree -exampleBst = undefined - --- contains only even -onlyHasEven :: Tree -> Bool +module Outside where +import Set +import BinarySearchTrees + +-- Set of 2,4,8,16,32,64 +exampleSet :: Set +exampleSet = undefined + +-- when are 2 sets equal? +eqSet :: Set -> Set -> Bool +eqSet _ _ = undefined + + +-- Tree of 2,4,8,16,32,64 +exampleBst :: Tree +exampleBst = undefined + +-- contains only even +onlyHasEven :: Tree -> Bool onlyHasEven _ = undefined \ No newline at end of file diff --git a/assignments/week3/hw/src/Set.hs b/assignments/week3/hw/src/Set.hs index 87c8547..09fa153 100644 --- a/assignments/week3/hw/src/Set.hs +++ b/assignments/week3/hw/src/Set.hs @@ -1,38 +1,38 @@ -module Set (Set, empty, contains, insert, isSubSet, union, intersection) where - - -type Set = [Integer] - - -empty :: Set -empty = undefined - -contains :: Set -> Integer -> Bool -contains = undefined - - -insert :: Integer -> Set -> Set -insert = undefined - - --- Functions on lists, using built-in lists - -isPrefix :: Set -> Set -> Bool -isPrefix = undefined - -isSubSet :: Set -> Set -> Bool -isSubSet = undefined - - --- find the union of two ordered lists, this is like merge but --- removing duplicates - -union :: Set -> Set -> Set -union = undefined - - --- find the intersection of two ordered lists, i.e., the --- common subsequence - -intersection :: Set -> Set -> Set -intersection = undefined +module Set (Set, empty, contains, insert, isSubSet, union, intersection) where + + +type Set = [Integer] + + +empty :: Set +empty = undefined + +contains :: Set -> Integer -> Bool +contains = undefined + + +insert :: Integer -> Set -> Set +insert = undefined + + +-- Functions on lists, using built-in lists + +isPrefix :: Set -> Set -> Bool +isPrefix = undefined + +isSubSet :: Set -> Set -> Bool +isSubSet = undefined + + +-- find the union of two ordered lists, this is like merge but +-- removing duplicates + +union :: Set -> Set -> Set +union = undefined + + +-- find the intersection of two ordered lists, i.e., the +-- common subsequence + +intersection :: Set -> Set -> Set +intersection = undefined diff --git a/assignments/week3/hw/src/TypeProblems.hs b/assignments/week3/hw/src/TypeProblems.hs index bfecfbb..cd6f6ac 100644 --- a/assignments/week3/hw/src/TypeProblems.hs +++ b/assignments/week3/hw/src/TypeProblems.hs @@ -1,62 +1,62 @@ -module TypeProblems where - - -data Answer a = Impossible | Example a - - --- Give Example definitions that have the following types if it is possible, If not return "Impossible". It does not matter what the definitions actually do as long AS they are correctly typed, they do not "loop forever", and they do not use undefined. - -q1 :: Answer [Bool] -q1 = undefined - -q2 :: Answer ([(Int,Char)],Bool) -q2 = undefined - -q3 :: Answer (Int -> Bool -> Char -> Int -> Bool) -q3 = undefined - -q4 :: Answer (a -> ([a],[a],[a])) -q4 = undefined - - -q5 :: Answer (a -> b) -q5 = undefined - -q6 :: Answer (a -> a) -q6 = undefined - --- but different then above -q7 :: Answer (a -> a) -q7 = undefined - -q8 :: Answer (a -> a -> a) -q8 = undefined - --- but different then above -q9 :: Answer (a -> a -> a) -q9 = undefined - - -q10 :: Answer (a -> b -> a) -q10 = undefined - -q11 :: Answer (a -> b -> b) -q11 = undefined - -q12 :: Answer ((a -> b) -> b) -q12 = undefined - -q13 :: Answer ((a -> b) -> (Maybe b)) -q13 = undefined - -q14 :: Answer (a -> b -> (b,a)) -q14 = undefined - -q15 :: Answer ((a -> b) -> (b -> c) -> (a -> c)) -q15 = undefined - -q16 :: Answer ((a -> b) -> (b -> c) -> (c -> a)) -q16 = undefined - -q17 :: Answer ((a -> b) -> ([b] -> c) -> c) -q17 = undefined +module TypeProblems where + + +data Answer a = Impossible | Example a + + +-- Give Example definitions that have the following types if it is possible, If not return "Impossible". It does not matter what the definitions actually do as long AS they are correctly typed, they do not "loop forever", and they do not use undefined. + +q1 :: Answer [Bool] +q1 = undefined + +q2 :: Answer ([(Int,Char)],Bool) +q2 = undefined + +q3 :: Answer (Int -> Bool -> Char -> Int -> Bool) +q3 = undefined + +q4 :: Answer (a -> ([a],[a],[a])) +q4 = undefined + + +q5 :: Answer (a -> b) +q5 = undefined + +q6 :: Answer (a -> a) +q6 = undefined + +-- but different then above +q7 :: Answer (a -> a) +q7 = undefined + +q8 :: Answer (a -> a -> a) +q8 = undefined + +-- but different then above +q9 :: Answer (a -> a -> a) +q9 = undefined + + +q10 :: Answer (a -> b -> a) +q10 = undefined + +q11 :: Answer (a -> b -> b) +q11 = undefined + +q12 :: Answer ((a -> b) -> b) +q12 = undefined + +q13 :: Answer ((a -> b) -> (Maybe b)) +q13 = undefined + +q14 :: Answer (a -> b -> (b,a)) +q14 = undefined + +q15 :: Answer ((a -> b) -> (b -> c) -> (a -> c)) +q15 = undefined + +q16 :: Answer ((a -> b) -> (b -> c) -> (c -> a)) +q16 = undefined + +q17 :: Answer ((a -> b) -> ([b] -> c) -> c) +q17 = undefined diff --git a/assignments/week3/hw/tests/DataProblemsTest.hs b/assignments/week3/hw/tests/DataProblemsTest.hs index 5a4a2c9..d88910c 100644 --- a/assignments/week3/hw/tests/DataProblemsTest.hs +++ b/assignments/week3/hw/tests/DataProblemsTest.hs @@ -1,35 +1,35 @@ -module DataProblemsTest where - -import Test.Tasty (defaultMain, testGroup) -import Test.Tasty.HUnit (assertEqual, assertBool, testCase) - -import DataProblems(Deserts, favorite, dontLike, willILikeIt, Student, me, mkStudent) - -import Data.Maybe - -unitTests = - testGroup - "DataProblems" - [ - ex1willILikeIt, - ex1willILikeNot, - correctInvalidStudent, - canMakeSomeStudents - ] - -ex1willILikeIt = - testCase "favorite should be true" $ assertBool [] (willILikeIt favorite) - -ex1willILikeNot = - testCase "dontLike should be false" $ assertBool [] (not (willILikeIt dontLike)) - --- mkstudent year= -12930454 should be None -correctInvalidStudent = - testCase "Correct Invalid Student" $ assertBool [] (isNothing (mkStudent "a" "b" "1243423" (-12930454))) - --- there are cleaner ways to do this -someStudents :: [Student] -someStudents = map (\ (Just s) -> s) $ filter isJust $ map (\ i -> (mkStudent "a" "b" "1243423" (i))) [0..3000] - -canMakeSomeStudents = +module DataProblemsTest where + +import Test.Tasty (defaultMain, testGroup) +import Test.Tasty.HUnit (assertEqual, assertBool, testCase) + +import DataProblems(Deserts, favorite, dontLike, willILikeIt, Student, me, mkStudent) + +import Data.Maybe + +unitTests = + testGroup + "DataProblems" + [ + ex1willILikeIt, + ex1willILikeNot, + correctInvalidStudent, + canMakeSomeStudents + ] + +ex1willILikeIt = + testCase "favorite should be true" $ assertBool [] (willILikeIt favorite) + +ex1willILikeNot = + testCase "dontLike should be false" $ assertBool [] (not (willILikeIt dontLike)) + +-- mkstudent year= -12930454 should be None +correctInvalidStudent = + testCase "Correct Invalid Student" $ assertBool [] (isNothing (mkStudent "a" "b" "1243423" (-12930454))) + +-- there are cleaner ways to do this +someStudents :: [Student] +someStudents = map (\ (Just s) -> s) $ filter isJust $ map (\ i -> (mkStudent "a" "b" "1243423" (i))) [0..3000] + +canMakeSomeStudents = testCase "Can make some students" $ assertBool [] (0 /= length someStudents) \ No newline at end of file diff --git a/assignments/week3/hw/tests/OutsideTest.hs b/assignments/week3/hw/tests/OutsideTest.hs index 98ffa1b..b17f35d 100644 --- a/assignments/week3/hw/tests/OutsideTest.hs +++ b/assignments/week3/hw/tests/OutsideTest.hs @@ -1,70 +1,70 @@ -module OutsideTest where - -import Test.Tasty (defaultMain, testGroup) -import Test.Tasty.HUnit (assertEqual, assertBool, testCase) - -import Outside(exampleSet, eqSet, exampleBst, onlyHasEven) - -import Outside(exampleSet, eqSet, exampleBst, onlyHasEven) -import Set(Set(..), empty, insert) -import BinarySearchTrees(Tree(..), insert, eq) - -unitTests = - testGroup - "Outside" - [ - ex1ExampleSet, - ex1ExampleSet, - ex1EqSet, - ex2EqSet, - ex3EqSet, - ex4EqSet, - ex1ExampleBST, - ex1onlyHasEven, - ex2onlyHasEven, - ex3onlyHasEven - ] - -insertAllBst :: [Integer] -> Tree -insertAllBst [] = Null -insertAllBst (h:t) = BinarySearchTrees.insert h $ insertAllBst t - -insertAllSet :: [Integer] -> Set -insertAllSet [] = empty -insertAllSet (h:t) = Set.insert h $ insertAllSet t - -exampleSet1 = insertAllSet [2, 4, 8, 16, 32, 64] -exampleSet2 = insertAllSet [2, 4, 8, 16, 32] -exampleBst1 = insertAllBst [2, 4, 8, 16, 32, 64] -exampleBst2 = insertAllBst [2, 4, 8, 16, 32, 63] - -ex1ExampleSet = - testCase "example set is equal" $ assertBool [] $ eqSet exampleSet1 exampleSet1 - -ex1EqSet = - testCase "EQUAL: exampleSet1 is equal to exampleSet1 is correct" $ assertBool [] $ eqSet exampleSet1 exampleSet1 - -ex2EqSet = - testCase "EQUAL: empty is equal to empty" $ assertBool [] $ eqSet empty empty - -ex3EqSet = - testCase "EQUAL: empty is not equal to exampleSet1" $ assertBool [] $ not (eqSet empty exampleSet1) - -ex4EqSet = - testCase "EQUAL: exampleSet1 is not equal to exampleSet2" $ assertBool [] $ not (eqSet exampleSet2 exampleSet1) - -ex1ExampleBST = - testCase "exampleBST is equal to the generated insert" $ assertBool [] $ eq exampleBst1 exampleBst - -ex1onlyHasEven = - testCase "exampleBst1 has only even numbers" $ assertBool [] $ onlyHasEven exampleBst1 - -ex2onlyHasEven = - testCase "exampleBst2 one odd number" $ assertBool [] $ not (onlyHasEven exampleBst2) - -ex3onlyHasEven = - testCase "Null is not even" $ assertBool [] $ not (onlyHasEven Null) - - - +module OutsideTest where + +import Test.Tasty (defaultMain, testGroup) +import Test.Tasty.HUnit (assertEqual, assertBool, testCase) + +import Outside(exampleSet, eqSet, exampleBst, onlyHasEven) + +import Outside(exampleSet, eqSet, exampleBst, onlyHasEven) +import Set(Set(..), empty, insert) +import BinarySearchTrees(Tree(..), insert, eq) + +unitTests = + testGroup + "Outside" + [ + ex1ExampleSet, + ex1ExampleSet, + ex1EqSet, + ex2EqSet, + ex3EqSet, + ex4EqSet, + ex1ExampleBST, + ex1onlyHasEven, + ex2onlyHasEven, + ex3onlyHasEven + ] + +insertAllBst :: [Integer] -> Tree +insertAllBst [] = Null +insertAllBst (h:t) = BinarySearchTrees.insert h $ insertAllBst t + +insertAllSet :: [Integer] -> Set +insertAllSet [] = empty +insertAllSet (h:t) = Set.insert h $ insertAllSet t + +exampleSet1 = insertAllSet [2, 4, 8, 16, 32, 64] +exampleSet2 = insertAllSet [2, 4, 8, 16, 32] +exampleBst1 = insertAllBst [2, 4, 8, 16, 32, 64] +exampleBst2 = insertAllBst [2, 4, 8, 16, 32, 63] + +ex1ExampleSet = + testCase "example set is equal" $ assertBool [] $ eqSet exampleSet1 exampleSet1 + +ex1EqSet = + testCase "EQUAL: exampleSet1 is equal to exampleSet1 is correct" $ assertBool [] $ eqSet exampleSet1 exampleSet1 + +ex2EqSet = + testCase "EQUAL: empty is equal to empty" $ assertBool [] $ eqSet empty empty + +ex3EqSet = + testCase "EQUAL: empty is not equal to exampleSet1" $ assertBool [] $ not (eqSet empty exampleSet1) + +ex4EqSet = + testCase "EQUAL: exampleSet1 is not equal to exampleSet2" $ assertBool [] $ not (eqSet exampleSet2 exampleSet1) + +ex1ExampleBST = + testCase "exampleBST is equal to the generated insert" $ assertBool [] $ eq exampleBst1 exampleBst + +ex1onlyHasEven = + testCase "exampleBst1 has only even numbers" $ assertBool [] $ onlyHasEven exampleBst1 + +ex2onlyHasEven = + testCase "exampleBst2 one odd number" $ assertBool [] $ not (onlyHasEven exampleBst2) + +ex3onlyHasEven = + testCase "Null is not even" $ assertBool [] $ not (onlyHasEven Null) + + + \ No newline at end of file diff --git a/assignments/week3/hw/tests/SetTest.hs b/assignments/week3/hw/tests/SetTest.hs index 13986cc..a1c736e 100644 --- a/assignments/week3/hw/tests/SetTest.hs +++ b/assignments/week3/hw/tests/SetTest.hs @@ -1,76 +1,76 @@ -module SetTest where - -import Test.Tasty (defaultMain, testGroup) -import Test.Tasty.HUnit (assertEqual, assertBool, testCase) - -import Set(Set, empty, insert, contains, isSubSet, union, intersection) - -unitTests = - testGroup - "Set" - [ - ex1Insert, - ex2Insert, - ex3Insert, - ex1Contains, - ex2Contains, - ex3Contains, - ex1IsSubset, - ex2IsSubset, - ex3IsSubset, - ex1Union, - ex2Union, - ex3Union, - ex1intersection, - ex2intersection - ] - - -exampleSet1 = [3, 4, 8, 10, 17] -exampleSet2 = [3, 4, 17] -exampleSet3 = [6, 8, 9, 10] -exampleSet4 = [6, 8, 9] -union13 = [3, 4, 6, 8, 9, 10, 17] -intersection13 = [8, 10] - -ex1Insert = - testCase "insert 10 in exampleSet4" $ assertEqual [] exampleSet3 (insert 10 exampleSet4) - -ex2Insert = - testCase "insert 8 10 in null" $ assertEqual [] intersection13 (insert 10 (insert 8 empty)) - -ex3Insert = - testCase "insert .. in null" $ assertEqual [] union13 (insert 9 (insert 10 (insert 6 (insert 8 (insert 10 (insert 3 (insert 17 (insert 4 empty)))))))) - -ex1Contains = - testCase "empty set doesn't contain 9" $ assertBool [] (not (contains empty 9)) - -ex2Contains = - testCase "exampleSet1 contains 10" $ assertBool [] (contains exampleSet1 10) - -ex3Contains = - testCase "exampleSet1 doesn't contain 7" $ assertBool [] (not (contains exampleSet1 7)) - -ex1IsSubset = - testCase "exampleSet2 is a subset of exampleSet1" $ assertBool [] (isSubSet exampleSet2 exampleSet1) - -ex2IsSubset = - testCase "exampleSet3 is not a subset of exampleSet1" $ assertBool [] (not (isSubSet exampleSet3 exampleSet1)) - -ex3IsSubset = - testCase "empty is a subset of exampleSet1" $ assertBool [] (isSubSet [] exampleSet1) - -ex1Union = - testCase "union of exampleSet1 & 3" $ assertEqual [] union13 (union exampleSet1 exampleSet3) - -ex2Union = - testCase "union of empty and exampleSet1" $ assertEqual [] exampleSet1 (union exampleSet1 []) - -ex3Union = - testCase "union of exampleSet2 and exampleSet1" $ assertEqual [] exampleSet1 (union exampleSet1 exampleSet2) - -ex1intersection = - testCase "intersection of exampleSet1 & 3" $ assertEqual [] intersection13 (intersection exampleSet1 exampleSet3) - -ex2intersection = - testCase "empty is the intersection of exampleSet2 & intersection13" $ assertEqual [] empty (intersection exampleSet2 intersection13) +module SetTest where + +import Test.Tasty (defaultMain, testGroup) +import Test.Tasty.HUnit (assertEqual, assertBool, testCase) + +import Set(Set, empty, insert, contains, isSubSet, union, intersection) + +unitTests = + testGroup + "Set" + [ + ex1Insert, + ex2Insert, + ex3Insert, + ex1Contains, + ex2Contains, + ex3Contains, + ex1IsSubset, + ex2IsSubset, + ex3IsSubset, + ex1Union, + ex2Union, + ex3Union, + ex1intersection, + ex2intersection + ] + + +exampleSet1 = [3, 4, 8, 10, 17] +exampleSet2 = [3, 4, 17] +exampleSet3 = [6, 8, 9, 10] +exampleSet4 = [6, 8, 9] +union13 = [3, 4, 6, 8, 9, 10, 17] +intersection13 = [8, 10] + +ex1Insert = + testCase "insert 10 in exampleSet4" $ assertEqual [] exampleSet3 (insert 10 exampleSet4) + +ex2Insert = + testCase "insert 8 10 in null" $ assertEqual [] intersection13 (insert 10 (insert 8 empty)) + +ex3Insert = + testCase "insert .. in null" $ assertEqual [] union13 (insert 9 (insert 10 (insert 6 (insert 8 (insert 10 (insert 3 (insert 17 (insert 4 empty)))))))) + +ex1Contains = + testCase "empty set doesn't contain 9" $ assertBool [] (not (contains empty 9)) + +ex2Contains = + testCase "exampleSet1 contains 10" $ assertBool [] (contains exampleSet1 10) + +ex3Contains = + testCase "exampleSet1 doesn't contain 7" $ assertBool [] (not (contains exampleSet1 7)) + +ex1IsSubset = + testCase "exampleSet2 is a subset of exampleSet1" $ assertBool [] (isSubSet exampleSet2 exampleSet1) + +ex2IsSubset = + testCase "exampleSet3 is not a subset of exampleSet1" $ assertBool [] (not (isSubSet exampleSet3 exampleSet1)) + +ex3IsSubset = + testCase "empty is a subset of exampleSet1" $ assertBool [] (isSubSet [] exampleSet1) + +ex1Union = + testCase "union of exampleSet1 & 3" $ assertEqual [] union13 (union exampleSet1 exampleSet3) + +ex2Union = + testCase "union of empty and exampleSet1" $ assertEqual [] exampleSet1 (union exampleSet1 []) + +ex3Union = + testCase "union of exampleSet2 and exampleSet1" $ assertEqual [] exampleSet1 (union exampleSet1 exampleSet2) + +ex1intersection = + testCase "intersection of exampleSet1 & 3" $ assertEqual [] intersection13 (intersection exampleSet1 exampleSet3) + +ex2intersection = + testCase "empty is the intersection of exampleSet2 & intersection13" $ assertEqual [] empty (intersection exampleSet2 intersection13) diff --git a/assignments/week3/hw/tests/TypeProblemsTest.hs b/assignments/week3/hw/tests/TypeProblemsTest.hs index e33819d..382b88d 100644 --- a/assignments/week3/hw/tests/TypeProblemsTest.hs +++ b/assignments/week3/hw/tests/TypeProblemsTest.hs @@ -1,34 +1,34 @@ -module TypeProblemsTest where - -import Test.Tasty (defaultMain, testGroup) -import Test.Tasty.HUnit (assertEqual, assertBool, testCase) - -import TypeProblems(Answer(..), q1,q2,q3,q4,q5,q6,q7,q8,q9,q10,q11,q12,q13,q14,q15,q16,q17) -import Data.Bits -import Data.Char -import Data.Maybe - -unitTests = - testGroup - "TypeProblems" - [differentQ6Q7,differentQ8Q9] - --- for simple stuff -instance Eq a => Eq (Answer a) where - Impossible == Impossible = True - (Example x) == (Example y) = x == y - _ == _ = False - -checkDifferent :: (Answer a) -> (Answer a) -> (a -> a -> Bool) -> Bool -checkDifferent Impossible _ _ = True -checkDifferent _ Impossible _ = True -checkDifferent (Example x) (Example y) f = f x y - - -differentQ6Q7 = - testCase "q6 different than q7 (different functions take one same input to differnt outputs)" $ assertBool [] $ checkDifferent q6 q7 (\a1 a2 -> a1 () /= a2 ()) -differentQ8Q9 = - testCase "q8 different than q8 (different functions take one same input to differnt outputs)" $ assertBool [] $ checkDifferent q8 q9 (\a1 a2 -> a1 True False /= a2 True False ) - - ---unfortunately pretty much any other test gives away the answers +module TypeProblemsTest where + +import Test.Tasty (defaultMain, testGroup) +import Test.Tasty.HUnit (assertEqual, assertBool, testCase) + +import TypeProblems(Answer(..), q1,q2,q3,q4,q5,q6,q7,q8,q9,q10,q11,q12,q13,q14,q15,q16,q17) +import Data.Bits +import Data.Char +import Data.Maybe + +unitTests = + testGroup + "TypeProblems" + [differentQ6Q7,differentQ8Q9] + +-- for simple stuff +instance Eq a => Eq (Answer a) where + Impossible == Impossible = True + (Example x) == (Example y) = x == y + _ == _ = False + +checkDifferent :: (Answer a) -> (Answer a) -> (a -> a -> Bool) -> Bool +checkDifferent Impossible _ _ = True +checkDifferent _ Impossible _ = True +checkDifferent (Example x) (Example y) f = f x y + + +differentQ6Q7 = + testCase "q6 different than q7 (different functions take one same input to differnt outputs)" $ assertBool [] $ checkDifferent q6 q7 (\a1 a2 -> a1 () /= a2 ()) +differentQ8Q9 = + testCase "q8 different than q8 (different functions take one same input to differnt outputs)" $ assertBool [] $ checkDifferent q8 q9 (\a1 a2 -> a1 True False /= a2 True False ) + + +--unfortunately pretty much any other test gives away the answers diff --git a/assignments/week4/hw/src/IndexAndConcordance.hs b/assignments/week4/hw/src/IndexAndConcordance.hs index b68b995..1f45b6e 100644 --- a/assignments/week4/hw/src/IndexAndConcordance.hs +++ b/assignments/week4/hw/src/IndexAndConcordance.hs @@ -1,98 +1,98 @@ -module IndexAndConcordance where -import IndexTree - -import Data.Char - - --- Concordance Builder: an example of using index tree - --- Suppose you have a book, and you want to create an concordance, --- i.e., a list of words and page numbers where those words --- appear. One way to do this is to create an index giving --- all the words on each page, using the page number as --- key (starting at 1), and all the words on that page as the value. Then, --- when you invert the index you have--voila!--a keys --- which are words, and values which are lists of page --- numbers where those words occur. In this problem we will --- do a toy version of this process, using a simplified --- version of a "book." - --- A book is a list of strings, each string representing the --- text on the page. We will remove punctuation and change --- all letters to lower case, and then split it Integero words. - - -book = [ "This, to start, is the first page.", "This is the second page of two!", "This is the third of three." ] - -punctuation = ".,!?()-_" - --- Replace all punctuation as just defined with spaces and --- changes all upper-case letters to lower. --- HInteger: use elem from the Prelude and toLower from Data.Char --- Example: --- > cleanup "hi there,this is Wayne,--er,Prof Snyder!" --- > "hi there this is wayne er prof snyder " - -cleanup :: String -> String -cleanup = undefined - - --- This takes a list of strings, and creates a list of cleaned up lists of words on each page --- HInteger: map cleanup and words (from Prelude) over the list. --- Example: --- > createWordLists ["hi there this is wayne", " er prof snyder "] --- > [["hi","there","this","is","wayne"],["er","prof","snyder"]] - -createWordLists :: [String] -> [[String]] -createWordLists = undefined - --- Now take the list of words, and replace it with a list of (key,value) pairs --- with key being the page number (starting at 1) and value being the list of words. --- You may find it useful to define a helper function. --- Example: --- > makePairs [["hi","there","this","is","wayne"],["er","prof","snyder"]] --- > [(1,["hi","there","this","is","wayne"]),(2,["er","prof","snyder"])] - - -makePairs :: [[String]] -> [(Integer,[String])] -makePairs = undefined - --- Now create a function to map this over each list to make a list of (Integer,String) pages for insertion in index tree --- Example: --- > addPageNumber (1,["hi","there","this","is","wayne"]) --- > [(1,"hi"),(1,"there"),(1,"this"),(1,"is"),(1,"wayne")] - - -addPageNumber :: (Integer,[String]) -> [(Integer,String)] -addPageNumber = undefined - - --- Now create a list of all such pairs for all pages: simply map the previous function over all --- lists of words, and then flatten (you wrote this for another part of the assignment, you can --- copy it here if wish) to create a list of all (n,w) pairs for page number n and word w. --- HInteger: compose all the previous ideas. - -createWordList :: [String] -> [(Integer, String)] -createWordList = undefined - --- Now write a function to insert a list of pairs Integero an index tree - -insertAll :: [(Integer, String)] -> IndexTree Integer String -insertAll = undefined - - --- Now create the tree and then invert it - -makeConcordance b = undefined - --- NOTE: you could have simply flipped the pairs after creating the word list, and this would give you --- the inverted index, but it is possible you want the original tree as well (both are common and --- useful in literary studies). In any case, it is one approach out of several equally valid. --- Please do it our way for now! - - - -c = makeConcordance book - --- Try the following: --- lookupKey "start" c +module IndexAndConcordance where +import IndexTree + +import Data.Char + + +-- Concordance Builder: an example of using index tree + +-- Suppose you have a book, and you want to create an concordance, +-- i.e., a list of words and page numbers where those words +-- appear. One way to do this is to create an index giving +-- all the words on each page, using the page number as +-- key (starting at 1), and all the words on that page as the value. Then, +-- when you invert the index you have--voila!--a keys +-- which are words, and values which are lists of page +-- numbers where those words occur. In this problem we will +-- do a toy version of this process, using a simplified +-- version of a "book." + +-- A book is a list of strings, each string representing the +-- text on the page. We will remove punctuation and change +-- all letters to lower case, and then split it Integero words. + + +book = [ "This, to start, is the first page.", "This is the second page of two!", "This is the third of three." ] + +punctuation = ".,!?()-_" + +-- Replace all punctuation as just defined with spaces and +-- changes all upper-case letters to lower. +-- HInteger: use elem from the Prelude and toLower from Data.Char +-- Example: +-- > cleanup "hi there,this is Wayne,--er,Prof Snyder!" +-- > "hi there this is wayne er prof snyder " + +cleanup :: String -> String +cleanup = undefined + + +-- This takes a list of strings, and creates a list of cleaned up lists of words on each page +-- HInteger: map cleanup and words (from Prelude) over the list. +-- Example: +-- > createWordLists ["hi there this is wayne", " er prof snyder "] +-- > [["hi","there","this","is","wayne"],["er","prof","snyder"]] + +createWordLists :: [String] -> [[String]] +createWordLists = undefined + +-- Now take the list of words, and replace it with a list of (key,value) pairs +-- with key being the page number (starting at 1) and value being the list of words. +-- You may find it useful to define a helper function. +-- Example: +-- > makePairs [["hi","there","this","is","wayne"],["er","prof","snyder"]] +-- > [(1,["hi","there","this","is","wayne"]),(2,["er","prof","snyder"])] + + +makePairs :: [[String]] -> [(Integer,[String])] +makePairs = undefined + +-- Now create a function to map this over each list to make a list of (Integer,String) pages for insertion in index tree +-- Example: +-- > addPageNumber (1,["hi","there","this","is","wayne"]) +-- > [(1,"hi"),(1,"there"),(1,"this"),(1,"is"),(1,"wayne")] + + +addPageNumber :: (Integer,[String]) -> [(Integer,String)] +addPageNumber = undefined + + +-- Now create a list of all such pairs for all pages: simply map the previous function over all +-- lists of words, and then flatten (you wrote this for another part of the assignment, you can +-- copy it here if wish) to create a list of all (n,w) pairs for page number n and word w. +-- HInteger: compose all the previous ideas. + +createWordList :: [String] -> [(Integer, String)] +createWordList = undefined + +-- Now write a function to insert a list of pairs Integero an index tree + +insertAll :: [(Integer, String)] -> IndexTree Integer String +insertAll = undefined + + +-- Now create the tree and then invert it + +makeConcordance b = undefined + +-- NOTE: you could have simply flipped the pairs after creating the word list, and this would give you +-- the inverted index, but it is possible you want the original tree as well (both are common and +-- useful in literary studies). In any case, it is one approach out of several equally valid. +-- Please do it our way for now! + + + +c = makeConcordance book + +-- Try the following: +-- lookupKey "start" c diff --git a/assignments/week4/hw/tests/IndexAndConcordanceTest.hs b/assignments/week4/hw/tests/IndexAndConcordanceTest.hs index cab1b38..c89653a 100644 --- a/assignments/week4/hw/tests/IndexAndConcordanceTest.hs +++ b/assignments/week4/hw/tests/IndexAndConcordanceTest.hs @@ -1,33 +1,33 @@ -module IndexAndConcordanceTest where - -import Test.Tasty (testGroup) -import Test.Tasty.HUnit (assertEqual, assertBool, testCase) - -import IndexAndConcordance(cleanup,createWordLists,makePairs, addPageNumber, createWordList, insertAll, makeConcordance) - - -unitTests = - testGroup - "IndexAndConcordanceTest" - [cleanUpTest, testingAddPageNum ,createWordListsTest - ] - -str1 = "Hey there student, I hope your test case did not FAIL. LOSER." -str1Ans = "hey there student i hope your test case did not fail loser " - -str2 = "Okay, this is string 2, it's not really very useful but it does the JOB." - -strList = [str1, str2] -createWordListsAnswer = [["hey","there","student","i","hope","your","test","case","did","not","fail","loser"],["okay","this","is","string","2","it's","not","really","very","useful","but","it","does","the","job"]] - -str = ["hi","there","this","is","a", "test", "CASE"] -answer = [(1,"hi"),(1,"there"),(1,"this"),(1,"is"),(1,"a"),(1,"test"),(1,"CASE")] - -cleanUpTest = - testCase "should return: hey there student i hope your test case did not fail loser " $ assertEqual [] (str1Ans) (cleanup str1) - -createWordListsTest = - testCase "output is incorrect, please check test file for answer" $ assertEqual [] (createWordListsAnswer) (createWordLists strList) -testingAddPageNum = testCase "should return: [(1,'hi'),(1,'there'),(1,'this'),(1,'is'),(1,'a'),(1,'test'),(1,'CASE')]" $ assertEqual [] answer (addPageNumber (1,str)) - - +module IndexAndConcordanceTest where + +import Test.Tasty (testGroup) +import Test.Tasty.HUnit (assertEqual, assertBool, testCase) + +import IndexAndConcordance(cleanup,createWordLists,makePairs, addPageNumber, createWordList, insertAll, makeConcordance) + + +unitTests = + testGroup + "IndexAndConcordanceTest" + [cleanUpTest, testingAddPageNum ,createWordListsTest + ] + +str1 = "Hey there student, I hope your test case did not FAIL. LOSER." +str1Ans = "hey there student i hope your test case did not fail loser " + +str2 = "Okay, this is string 2, it's not really very useful but it does the JOB." + +strList = [str1, str2] +createWordListsAnswer = [["hey","there","student","i","hope","your","test","case","did","not","fail","loser"],["okay","this","is","string","2","it's","not","really","very","useful","but","it","does","the","job"]] + +str = ["hi","there","this","is","a", "test", "CASE"] +answer = [(1,"hi"),(1,"there"),(1,"this"),(1,"is"),(1,"a"),(1,"test"),(1,"CASE")] + +cleanUpTest = + testCase "should return: hey there student i hope your test case did not fail loser " $ assertEqual [] (str1Ans) (cleanup str1) + +createWordListsTest = + testCase "output is incorrect, please check test file for answer" $ assertEqual [] (createWordListsAnswer) (createWordLists strList) +testingAddPageNum = testCase "should return: [(1,'hi'),(1,'there'),(1,'this'),(1,'is'),(1,'a'),(1,'test'),(1,'CASE')]" $ assertEqual [] answer (addPageNumber (1,str)) + + diff --git a/assignments/week5/hw/src/HigherOrderProblems.hs b/assignments/week5/hw/src/HigherOrderProblems.hs index c9f75d9..4e31134 100644 --- a/assignments/week5/hw/src/HigherOrderProblems.hs +++ b/assignments/week5/hw/src/HigherOrderProblems.hs @@ -1,38 +1,38 @@ -module HigherOrderProblems where - - - --- Write a function sumsq n, which returns the --- sum of the squares in the list n. We will use it to find the --- sum of the first k natural numbers: 1^2 + 2^2 + ... + k^2 --- Hint: use foldr, a helper function, and the list --- notation [1..k], which is the Haskell version of --- Pythons range(1,k+1). --- Example: sumsqa [1..4] => 30 -- 1 + 4 + 16 = 30 - -sumsqa :: [Integer] -> Integer -sumsqa n = undefined - - --- The function remdups removes adjacent duplicates from a list. --- Define remdups using foldr, with any helper function you need. --- Example: remdups [1, 2, 2, 3, 3, 3, 1, 1] => [1, 2, 3, 1] - -remdups :: Eq a => [a] -> [a] -remdups lst = undefined - - --- The function inits returns the list of all substring starting with the --- first character. --- Define inits using foldr and any helper function you need. --- Hint: the weird slice function (x:) will cons x onto the front of --- a list (try it!). Use this function with a map in your helper function. --- Example: inits "cs320" => ["", "c", "cs", "cs3", "cs32", "cs320"] - -inits :: [a] -> [[a]] -inits lst = undefined - - - - - +module HigherOrderProblems where + + + +-- Write a function sumsq n, which returns the +-- sum of the squares in the list n. We will use it to find the +-- sum of the first k natural numbers: 1^2 + 2^2 + ... + k^2 +-- Hint: use foldr, a helper function, and the list +-- notation [1..k], which is the Haskell version of +-- Pythons range(1,k+1). +-- Example: sumsqa [1..4] => 30 -- 1 + 4 + 16 = 30 + +sumsqa :: [Integer] -> Integer +sumsqa n = undefined + + +-- The function remdups removes adjacent duplicates from a list. +-- Define remdups using foldr, with any helper function you need. +-- Example: remdups [1, 2, 2, 3, 3, 3, 1, 1] => [1, 2, 3, 1] + +remdups :: Eq a => [a] -> [a] +remdups lst = undefined + + +-- The function inits returns the list of all substring starting with the +-- first character. +-- Define inits using foldr and any helper function you need. +-- Hint: the weird slice function (x:) will cons x onto the front of +-- a list (try it!). Use this function with a map in your helper function. +-- Example: inits "cs320" => ["", "c", "cs", "cs3", "cs32", "cs320"] + +inits :: [a] -> [[a]] +inits lst = undefined + + + + + diff --git a/assignments/week8/hw/.gitignore b/assignments/week8/hw/.gitignore index f01b768..a3d9c68 100644 --- a/assignments/week8/hw/.gitignore +++ b/assignments/week8/hw/.gitignore @@ -1,22 +1,22 @@ -dist -dist-* -cabal-dev -*.o -*.hi -*.chi -*.chs.h -*.dyn_o -*.dyn_hi -.hpc -.hsenv -.cabal-sandbox/ -cabal.sandbox.config -*.prof -*.aux -*.hp -*.eventlog -.stack-work/ -cabal.project.local -cabal.project.local~ -.HTF/ +dist +dist-* +cabal-dev +*.o +*.hi +*.chi +*.chs.h +*.dyn_o +*.dyn_hi +.hpc +.hsenv +.cabal-sandbox/ +cabal.sandbox.config +*.prof +*.aux +*.hp +*.eventlog +.stack-work/ +cabal.project.local +cabal.project.local~ +.HTF/ .ghc.environment.* \ No newline at end of file diff --git a/assignments/week8/hw/README.md b/assignments/week8/hw/README.md index a0aa414..37d1aeb 100644 --- a/assignments/week8/hw/README.md +++ b/assignments/week8/hw/README.md @@ -1,30 +1,30 @@ -# HW Due 10/30 -Lab and HW are combined this week. - -## Setup -Similar to [lab2](../../week2/lab2), Follow this [link](https://classroom.github.com/a/ogFzapTs) to create an assignment repository - -## Submit -similar to [lab2](../../week2/lab2) - -## REPL commands - * ```:load x``` will load a different module - * ```:reload``` reloads the module - * ```:type x``` tells you the type of x - * ```:q``` quits out of the REPL - - -## Hints - * parse smaller things, test and then parse bigger things with the smaller things - * start early and submit tests - * refresh the cabal REPL constantly! - * commit and push to your private repo often - * check your github private repo that you work has been submitted - * it is best to pull in form the upstream after you have committed and pushed to your private repo. - -## Notes -### 9:05 am -convinced me that it was to hard and I should give more solutions - - - +# HW Due 10/30 +Lab and HW are combined this week. + +## Setup +Similar to [lab2](../../week2/lab2), Follow this [link](https://classroom.github.com/a/ogFzapTs) to create an assignment repository + +## Submit +similar to [lab2](../../week2/lab2) + +## REPL commands + * ```:load x``` will load a different module + * ```:reload``` reloads the module + * ```:type x``` tells you the type of x + * ```:q``` quits out of the REPL + + +## Hints + * parse smaller things, test and then parse bigger things with the smaller things + * start early and submit tests + * refresh the cabal REPL constantly! + * commit and push to your private repo often + * check your github private repo that you work has been submitted + * it is best to pull in form the upstream after you have committed and pushed to your private repo. + +## Notes +### 9:05 am +convinced me that it was to hard and I should give more solutions + + + diff --git a/assignments/week8/hw/hw.cabal b/assignments/week8/hw/hw.cabal index c997772..5fe0e7e 100644 --- a/assignments/week8/hw/hw.cabal +++ b/assignments/week8/hw/hw.cabal @@ -1,32 +1,32 @@ -name: hw -version: 0.1.0.0 -synopsis: -homepage: -author: Mark -maintainer: lemay@bu.edu -category: -build-type: Simple -cabal-version: >=1.10 - - -library - exposed-modules: ExceptionMonad, ParserMonad, Arith, StateMonad, Lang3 - ghc-options: -fwarn-incomplete-patterns -fwarn-incomplete-uni-patterns - build-depends: containers, base >= 4.7 && < 5 - hs-source-dirs: src - default-language: Haskell2010 - -test-suite test - default-language: - Haskell2010 - type: - exitcode-stdio-1.0 --- TODO: detailed-1.0 is preferred - hs-source-dirs: - tests - main-is: Main.hs - other-modules: ArithTest,ExceptionMonadTest,Lang3Test,ParserMonadTest - build-depends: - containers, base >= 4.7 && < 5 - , tasty >= 0.11.1, tasty-hunit, tasty-quickcheck - , hw +name: hw +version: 0.1.0.0 +synopsis: +homepage: +author: Mark +maintainer: lemay@bu.edu +category: +build-type: Simple +cabal-version: >=1.10 + + +library + exposed-modules: ExceptionMonad, ParserMonad, Arith, StateMonad, Lang3 + ghc-options: -fwarn-incomplete-patterns -fwarn-incomplete-uni-patterns + build-depends: containers, base >= 4.7 && < 5 + hs-source-dirs: src + default-language: Haskell2010 + +test-suite test + default-language: + Haskell2010 + type: + exitcode-stdio-1.0 +-- TODO: detailed-1.0 is preferred + hs-source-dirs: + tests + main-is: Main.hs + other-modules: ArithTest,ExceptionMonadTest,Lang3Test,ParserMonadTest + build-depends: + containers, base >= 4.7 && < 5 + , tasty >= 0.11.1, tasty-hunit, tasty-quickcheck + , hw diff --git a/assignments/week8/hw/src/Arith.hs b/assignments/week8/hw/src/Arith.hs index 58e5234..38c1cb7 100644 --- a/assignments/week8/hw/src/Arith.hs +++ b/assignments/week8/hw/src/Arith.hs @@ -1,40 +1,40 @@ -module Arith where - -import ExceptionMonad -import ParserMonad - --- hint: read about the Rational type, fromIntegral might be helpful - --- write a full arithmetic language, it must have a nice show, eval and parser - --- your language must support numbers , addition, subtraction, multiplication, division - --- your parser must support the above and parentheses, natural numbers, white space, and standard precedence rules - --- your show should look nice, and should be parsable - --- ungraded bonus: handle negative numbers, decimals --- ungraded bonus: add operations like power or mod - -data Arith -- = Put your constructors here - - -eval :: Arith -> Unsafe Rational -eval = undefined - -parser :: Parser Arith -parser = undefined - --- a helper function --- parseArith :: String -> Maybe Arith --- parseArith s = fmap fst $ parse parser s - --- a human readable string -instance Show Arith where - show _ = undefined - - --- structural equality on your AST "2 + 2 /= 4" but "2*3 + 4*5" == "(2*3) + (4*5)" --- mostly for testing -instance Eq Arith where +module Arith where + +import ExceptionMonad +import ParserMonad + +-- hint: read about the Rational type, fromIntegral might be helpful + +-- write a full arithmetic language, it must have a nice show, eval and parser + +-- your language must support numbers , addition, subtraction, multiplication, division + +-- your parser must support the above and parentheses, natural numbers, white space, and standard precedence rules + +-- your show should look nice, and should be parsable + +-- ungraded bonus: handle negative numbers, decimals +-- ungraded bonus: add operations like power or mod + +data Arith -- = Put your constructors here + + +eval :: Arith -> Unsafe Rational +eval = undefined + +parser :: Parser Arith +parser = undefined + +-- a helper function +-- parseArith :: String -> Maybe Arith +-- parseArith s = fmap fst $ parse parser s + +-- a human readable string +instance Show Arith where + show _ = undefined + + +-- structural equality on your AST "2 + 2 /= 4" but "2*3 + 4*5" == "(2*3) + (4*5)" +-- mostly for testing +instance Eq Arith where _ == _ = undefined \ No newline at end of file diff --git a/assignments/week8/hw/src/ExceptionMonad.hs b/assignments/week8/hw/src/ExceptionMonad.hs index 3ae5fe4..43d5f2c 100644 --- a/assignments/week8/hw/src/ExceptionMonad.hs +++ b/assignments/week8/hw/src/ExceptionMonad.hs @@ -1,22 +1,22 @@ -module ExceptionMonad where -import Control.Monad(ap) - -data Unsafe a = Error String | Ok a deriving (Show, Eq) - -instance Functor Unsafe where - -- fmap :: (a -> b) -> Unsafe a -> Unsafe b - fmap f _ = undefined - -- hint: f :: a -> b - ---ignore this for now -instance Applicative Unsafe where - pure = return - (<*>) = ap - -instance Monad Unsafe where - --return :: a -> Unsafe a - return = undefined - - --(>>=) :: Unsafe a -> (a -> Unsafe b) -> Unsafe b - _ >>= f = undefined - -- hint: f :: a -> Unsafe b +module ExceptionMonad where +import Control.Monad(ap) + +data Unsafe a = Error String | Ok a deriving (Show, Eq) + +instance Functor Unsafe where + -- fmap :: (a -> b) -> Unsafe a -> Unsafe b + fmap f _ = undefined + -- hint: f :: a -> b + +--ignore this for now +instance Applicative Unsafe where + pure = return + (<*>) = ap + +instance Monad Unsafe where + --return :: a -> Unsafe a + return = undefined + + --(>>=) :: Unsafe a -> (a -> Unsafe b) -> Unsafe b + _ >>= f = undefined + -- hint: f :: a -> Unsafe b diff --git a/assignments/week8/hw/src/Lang3.hs b/assignments/week8/hw/src/Lang3.hs index 0bff315..03d26e4 100644 --- a/assignments/week8/hw/src/Lang3.hs +++ b/assignments/week8/hw/src/Lang3.hs @@ -1,42 +1,42 @@ -module Lang3 where - -import Prelude hiding (lookup) -import Data.Map(Map, lookup, insert, empty, fromList) -- for State - -import StateMonad - - -data Ast = - AstInt Integer - | Id String - | Plus Ast Ast - | Assign String Ast - | Separator Ast Ast - deriving Eq - -type State = Map String Integer - - --- some helper functions you might use --- --- these could also be done with do notation --- valOf :: String -> Stateful State Integer --- valOf var = Stateful $ \ s -> (case lookup var s of Nothing -> (0 ,s) --- Just i -> (i ,s)) --- --- setVal :: String -> Integer ->Stateful State () --- setVal var i = Stateful $ \ s -> (() , insert var i s) - - --- write eval, it should match https://github.com/BU-CS320/Fall-2018/blob/master/assignments/week7/hw/src/week5/Lang4.hs --- however, for simplicity, you may return 0 when you cannot find a var -eval :: Ast -> Stateful State Integer -eval = undefined - -instance Show Ast where - show (AstInt i) = show i - show (Plus x y) = "("++ show x ++ "+" ++ show y ++ ")" - show (Separator x y) = "("++ show x ++ ";" ++ show y ++ ")" - show (Assign x y) = "("++ show x ++ " = " ++ show y ++ ")" - show (Id x ) = x - +module Lang3 where + +import Prelude hiding (lookup) +import Data.Map(Map, lookup, insert, empty, fromList) -- for State + +import StateMonad + + +data Ast = + AstInt Integer + | Id String + | Plus Ast Ast + | Assign String Ast + | Separator Ast Ast + deriving Eq + +type State = Map String Integer + + +-- some helper functions you might use +-- +-- these could also be done with do notation +-- valOf :: String -> Stateful State Integer +-- valOf var = Stateful $ \ s -> (case lookup var s of Nothing -> (0 ,s) +-- Just i -> (i ,s)) +-- +-- setVal :: String -> Integer ->Stateful State () +-- setVal var i = Stateful $ \ s -> (() , insert var i s) + + +-- write eval, it should match https://github.com/BU-CS320/Fall-2018/blob/master/assignments/week7/hw/src/week5/Lang4.hs +-- however, for simplicity, you may return 0 when you cannot find a var +eval :: Ast -> Stateful State Integer +eval = undefined + +instance Show Ast where + show (AstInt i) = show i + show (Plus x y) = "("++ show x ++ "+" ++ show y ++ ")" + show (Separator x y) = "("++ show x ++ ";" ++ show y ++ ")" + show (Assign x y) = "("++ show x ++ " = " ++ show y ++ ")" + show (Id x ) = x + diff --git a/assignments/week8/hw/src/ParserMonad.hs b/assignments/week8/hw/src/ParserMonad.hs index dd4f046..c2e9ac4 100644 --- a/assignments/week8/hw/src/ParserMonad.hs +++ b/assignments/week8/hw/src/ParserMonad.hs @@ -1,3 +1,186 @@ +<<<<<<< HEAD +module ParserMonad where +import Control.Monad(ap) + +import Data.Char + +-- the type of a parser +-- these are the same as last time, but we wrap it in a data so we can define typeclasses on it +data Parser a = Parser (String -> Maybe (a, String)) + +-- a helper function to pull out the function bit (same as book) +parse :: Parser a -> (String -> Maybe (a, String)) +parse (Parser f) = f + + +instance Functor Parser where + -- fmap :: (a -> b) -> Parser a -> Parser b + fmap f (Parser pa) = undefined +-- hint: pa :: String -> Maybe (a, String) +-- hint: similar to State monad + +-- think, "does it follow the Functor laws?" + +--ignore this for now +instance Applicative Parser where + pure = return + (<*>) = ap + +instance Monad Parser where + --return :: a -> Parser a + return a = undefined + + --(>>=) :: Parser a -> (a -> Parser b) -> Parser b + (Parser pa) >>= f = undefined +-- hints: +-- pa :: String -> Maybe (a, String) +-- f :: a -> Parser b + +-- think, "does it follow the Monad laws?" + + + +-- parse one thing, if that works then parse the other thing +(+++) :: Parser a -> Parser b -> Parser (a,b) +pa +++ pb = undefined + +-- read in a char (from book) +item :: Parser Char +item = Parser $ \ input -> case input of "" -> Nothing + (h:t) -> Just (h, t) + + +-- a parser that always fails (empty in the book) +failParse :: Parser a +failParse = Parser $ \ input -> Nothing + + +-- read in a char if it passes a test, (from book) +sat :: (Char -> Bool) -> Parser Char +sat p = do c <- item + if p c + then return c + else failParse + + +-- parse exactly a string, return that string (in book as the poorly named "string") +literal :: String -> Parser String +literal "" = return "" +literal (h:t) = do sat (==h) + literal t + return (h:t) + +-- for example: +-- *ParserMonad> parse (literal "blahh") "blahhhhhh" +-- Just ("blahh","hhhh") + + + +exampleParser' = do literal "Let" + name <- literal "x" -- in real life this would be a var parser + literal "=" + nat <- literal "2" -- in real life this would be an Ast parser + literal "in" + body <- literal "3" --in real life this would be an Ast parser + return (name, nat, body) -- in real life this would call the right constructor + +-- for example: +-- *ParserMonad> parse exampleParser' "Letx=2in3" +-- Just (("x","2","3"),"") + + + +--try to parse a, if that doesn't work try to parse b (slightly different from the book) +(<|>) :: Parser a -> Parser b -> Parser (Either a b) +parserA <|> parserB = Parser $ \ input -> case parse parserA input of + Just (a, rest) -> Just (Left a, rest) + Nothing -> case parse parserB input of + Just (b, rest) -> Just (Right b, rest) + Nothing -> Nothing + +-- for example: +-- *ParserMonad> parse (literal "aa" <|> literal "bb") "aaaa" +-- Just (Left "aa","aa") +-- *ParserMonad> parse (literal "aa" <|> literal "bb") "bbb" +-- Just (Right "bb","b") + + + + +-- take a parser and parse as much as possible into a list, always parse at least 1 thing, (from book) +some :: Parser a -> Parser ([a]) +some pa = do a <- pa + rest <- rep pa + return (a:rest) + +-- for example: +-- *ParserMonad> parse (some (literal "blahh")) "blahhhhhh" +-- Just (["blahh"],"hhhh") +-- *ParserMonad> parse (some (literal "blahh")) "blahhblahhblahhblahhhhhh" +-- Just (["blahh","blahh","blahh","blahh"],"hhhh") +-- *ParserMonad> parse (some (literal "blahh")) "important instructions" +-- Nothing + + + +-- take a parser and parse as much as possible into a list, (in book as "many") +rep :: Parser a -> Parser ([a]) +rep pa = do res <- (some pa) <|> (return []) + case res of Left ls -> return ls + Right ls -> return ls + + +-- for example: +-- *ParserMonad> parse (rep (literal "blahh")) "blahhhhhh" +-- Just (["blahh"],"hhhh") +-- *ParserMonad> parse (rep (literal "blahh")) "blahhblahhblahhblahhhhhh" +-- Just (["blahh","blahh","blahh","blahh"],"hhhh") +-- *ParserMonad> parse (rep (literal "blahh")) "important instructions" +-- Just ([],"important instructions") + + +-- parse a digit (from book) +digit :: Parser Char +digit = sat isDigit + + +-- parse natural numbers, like "123", or "000230000" +natParser :: Parser Integer +natParser = do digits <- rep digit + return $ read digits + +-- for example: +-- *ParserMonad> parse natParser "12345" +-- Just (12345,"") + + +--parse spaces, throw them away +spaces :: Parser () +spaces = do rep (sat isSpace) + return () + +-- a nicer version of eat spaces, eat the spaces before or after the parser (from book) +token:: Parser a -> Parser a +token pa = do spaces + a <- pa + spaces + return a + + + +-- parse what we will consider a good variable name +-- hint: look up isAlpha +-- hint: you can do it like natParser +varParser :: Parser String +varParser = undefined + +exampleParser = do token $ literal "Let" + name <- varParser + token $ literal "=" + nat <- natParser --in real life this would be an Ast parser + token $ literal "in" + body <- natParser --in real life this would be an Ast parser +======= module ParserMonad where import Control.Monad(ap) @@ -179,4 +362,5 @@ exampleParser = do token $ literal "Let" nat <- natParser --in real life this would be an Ast parser token $ literal "in" body <- natParser --in real life this would be an Ast parser +>>>>>>> f83022ebbebc8bff0eac13707b2fd35c52ebfd5d return (name, nat, body) -- in real life this would call the right constructor \ No newline at end of file diff --git a/assignments/week8/hw/src/StateMonad.hs b/assignments/week8/hw/src/StateMonad.hs index c776d4b..cd59ee1 100644 --- a/assignments/week8/hw/src/StateMonad.hs +++ b/assignments/week8/hw/src/StateMonad.hs @@ -1,34 +1,34 @@ -module StateMonad where -import Control.Monad(ap) - --- notice how we handled state in https://github.com/BU-CS320/Fall-2018/blob/master/assignments/week7/hw/src/week5/Lang4.hs --- we can make a monadic type to handle the details for us -data Stateful s a = Stateful (s -> (a,s)) - --- a helper function to pull out the function bit -app :: Stateful s a -> (s ->(a,s)) -app (Stateful stateful) = stateful - -instance Functor (Stateful s) where - -- fmap :: (a -> b) -> Stateful a -> Stateful b - fmap f (Stateful sa) = Stateful $ \ state -> case sa state of - (a, output) -> (f a, output) - ---ignore this for now -instance Applicative (Stateful s) where - pure = return - (<*>) = ap - -instance Monad (Stateful s) where - --return :: a -> Stateful a - return a = Stateful $ \ state -> (a, state) - - --(>>=) :: Stateful a -> (a -> Stateful b) -> Stateful b - (Stateful sa) >>= f = Stateful $ \ state -> case sa state of - (a, output) -> app (f a) output - - --- a function that gets the state (in a stateful way) --- stolen from https://wiki.haskell.org/State_Monad -get :: Stateful s s +module StateMonad where +import Control.Monad(ap) + +-- notice how we handled state in https://github.com/BU-CS320/Fall-2018/blob/master/assignments/week7/hw/src/week5/Lang4.hs +-- we can make a monadic type to handle the details for us +data Stateful s a = Stateful (s -> (a,s)) + +-- a helper function to pull out the function bit +app :: Stateful s a -> (s ->(a,s)) +app (Stateful stateful) = stateful + +instance Functor (Stateful s) where + -- fmap :: (a -> b) -> Stateful a -> Stateful b + fmap f (Stateful sa) = Stateful $ \ state -> case sa state of + (a, output) -> (f a, output) + +--ignore this for now +instance Applicative (Stateful s) where + pure = return + (<*>) = ap + +instance Monad (Stateful s) where + --return :: a -> Stateful a + return a = Stateful $ \ state -> (a, state) + + --(>>=) :: Stateful a -> (a -> Stateful b) -> Stateful b + (Stateful sa) >>= f = Stateful $ \ state -> case sa state of + (a, output) -> app (f a) output + + +-- a function that gets the state (in a stateful way) +-- stolen from https://wiki.haskell.org/State_Monad +get :: Stateful s s get = Stateful $ \ s -> (s,s) \ No newline at end of file diff --git a/assignments/week8/hw/tests/ArithTest.hs b/assignments/week8/hw/tests/ArithTest.hs index 1e8d719..0c7cba2 100644 --- a/assignments/week8/hw/tests/ArithTest.hs +++ b/assignments/week8/hw/tests/ArithTest.hs @@ -1,3 +1,50 @@ +<<<<<<< HEAD +module ArithTest where + +import Test.Tasty (testGroup, TestTree) +import Test.Tasty.HUnit (assertEqual, assertBool, testCase) +import Test.Tasty.QuickCheck + +import ParserMonad +import ExceptionMonad +import Arith(Arith, eval, parser) + +unitTests = + testGroup + "ArithTest" + [instructorTests + ,ourTests + -- TODO: your tests here!!! + ] + + +shouldEvalToNum :: String -> Rational -> String -> TestTree +shouldEvalToNum s num parseThis = testCase (s ++ ": " ++ parseThis) $ assertEqual [] (Just (Ok num)) $ fmap (eval . fst) (parse parser parseThis) + +instructorTests = testGroup + "instructorTests" + [ shouldEvalToNum "" 0 "0", + shouldEvalToNum "" 15 "1 + 2 + 3 + 4 + 5", + shouldEvalToNum "" 15 "1 + (2 + 3) + ((4) + 5)", + shouldEvalToNum "" 24 "2 * 4 * 3", + shouldEvalToNum "" 6 "12 / 2 ", + shouldEvalToNum "" 12212 "22222 - 10 - 10000" + ] + +ourTests = testGroup + "ourTests" + [ shouldEvalToNum "" 512 "2^3^2" + , shouldEvalToNum "" 28 "2 + 4 * 6 + 2" + ] +-- TODO: your tests here!!! +-- TODO: test structural equality on your AST "2 + 2 /= 4" but "2*3 + 4*5" == "(2*3) + (4*5)" +-- TODO: every simple thing parses and evals +-- TODO: division by 0 gives an error, errors propagate correctly +-- TODO: many many examples +-- TODO: some really long example +-- TODO: for any valid Arith AST show should be parsable to the same AST +-- TODO: clean up shouldEvalToNum string (handle empty s better, show the AST?) +======= module ArithTest where import Test.Tasty (testGroup, TestTree) @@ -50,4 +97,5 @@ somemoreTests = testGroup testCase "Arith AST structral equality" $ assertBool [] ((parse parser "2*3 + 4*5") == (parse parser "(2*3) + (4*5)")), testCase "Arith AST structral inequality" $ assertBool [] ((parse parser "(1+2) * (2+1)") /= (parse parser "1 + 2 * 2 + 1")) - ] \ No newline at end of file + ] +>>>>>>> f83022ebbebc8bff0eac13707b2fd35c52ebfd5d diff --git a/assignments/week8/hw/tests/ExceptionMonadTest.hs b/assignments/week8/hw/tests/ExceptionMonadTest.hs index 943b07e..b34d380 100644 --- a/assignments/week8/hw/tests/ExceptionMonadTest.hs +++ b/assignments/week8/hw/tests/ExceptionMonadTest.hs @@ -1,25 +1,25 @@ -module ExceptionMonadTest where - -import Test.Tasty (testGroup) -import Test.Tasty.HUnit (assertEqual, assertBool, testCase) -import Test.Tasty.QuickCheck - -import ExceptionMonad (Unsafe(Error, Ok)) - -unitTests = - testGroup - "ExceptionMonadTest" - [instructorTests - -- TODO: your tests here!!! - ] - -instructorTests = testGroup - "instructorTests" - [ - testCase "return test " $ assertEqual [] (Ok 0) $ return 0, - testCase "return test " $ assertEqual [] (Ok 5) $ return 5 - ] - - --- TODO: your tests here!!! +module ExceptionMonadTest where + +import Test.Tasty (testGroup) +import Test.Tasty.HUnit (assertEqual, assertBool, testCase) +import Test.Tasty.QuickCheck + +import ExceptionMonad (Unsafe(Error, Ok)) + +unitTests = + testGroup + "ExceptionMonadTest" + [instructorTests + -- TODO: your tests here!!! + ] + +instructorTests = testGroup + "instructorTests" + [ + testCase "return test " $ assertEqual [] (Ok 0) $ return 0, + testCase "return test " $ assertEqual [] (Ok 5) $ return 5 + ] + + +-- TODO: your tests here!!! -- TODO: Lots of tests for all the laws! \ No newline at end of file diff --git a/assignments/week8/hw/tests/Lang3Test.hs b/assignments/week8/hw/tests/Lang3Test.hs index 5af62ed..386df84 100644 --- a/assignments/week8/hw/tests/Lang3Test.hs +++ b/assignments/week8/hw/tests/Lang3Test.hs @@ -1,3 +1,40 @@ +<<<<<<< HEAD +module Lang3Test where + +import Test.Tasty (testGroup) +import Test.Tasty.HUnit (assertEqual, assertBool, testCase) +import Test.Tasty.QuickCheck + +import Data.Map(Map, lookup, insert, empty, fromList) -- for State + +import Lang3(Ast(AstInt ,Id , Plus, Assign , Separator), eval) +import StateMonad + +unitTests = + testGroup + "Lang3Test" + [instructorTests + -- TODO: your tests here!!! + ] + +instructorTests = testGroup + "instructorTests" + [ + testCase "example eval, assign also returns it's value" $ assertEqual [] (3, fromList [("x",3)]) $ app (eval ("x" `Assign` (AstInt 3))) empty, + testCase "example eval on different states" $ assertBool [] $ fst (app (eval ("x" `Assign` ((AstInt 3) `Plus` (Id "x")))) empty) + /= + fst (app (eval ("x" `Assign` ((AstInt 3) `Plus` (Id "x")))) (fromList [("x",3)])), + + testCase "state is handled across addition" $ assertEqual [] (14) $ (fst (app (eval ((("x" `Assign` (AstInt 3)) `Plus` (Id "x")) `Plus` ( ("x" `Assign` (AstInt 4)) `Plus` (Id "x")) ) ) empty ) ) + + ] + + +-- TODO: your tests here!!! +-- TODO: Many, many more example test cases (every simple thing, many normal things, some extreame things) +-- TODO: add a generator, can then test more advanced language properties +-- TODO: you should always be able to parse show (when the var names aren't too bad) +======= module Lang3Test where import Test.Tasty (testGroup) @@ -34,3 +71,4 @@ instructorTests = testGroup -- TODO: test "(x=3);(x+x)" goes to 6 -- TODO: add a generator, can then test more advanced language properties -- TODO: you should always be able to parse show (when the var names aren't too bad) +>>>>>>> f83022ebbebc8bff0eac13707b2fd35c52ebfd5d diff --git a/assignments/week8/hw/tests/Main.hs b/assignments/week8/hw/tests/Main.hs index 349388f..63e58bd 100644 --- a/assignments/week8/hw/tests/Main.hs +++ b/assignments/week8/hw/tests/Main.hs @@ -1,22 +1,22 @@ -module Main where - -import Test.Tasty - -import ArithTest -import ExceptionMonadTest -import Lang3Test -import ParserMonadTest - -main = defaultMain testSuite - ---TODO: figure out how to set the timeout - -testSuite = - testGroup - "allTests" - [ - ArithTest.unitTests, - ExceptionMonadTest.unitTests, - Lang3Test.unitTests, - ParserMonadTest.unitTests - ] +module Main where + +import Test.Tasty + +import ArithTest +import ExceptionMonadTest +import Lang3Test +import ParserMonadTest + +main = defaultMain testSuite + +--TODO: figure out how to set the timeout + +testSuite = + testGroup + "allTests" + [ + ArithTest.unitTests, + ExceptionMonadTest.unitTests, + Lang3Test.unitTests, + ParserMonadTest.unitTests + ] diff --git a/assignments/week8/hw/tests/ParserMonadTest.hs b/assignments/week8/hw/tests/ParserMonadTest.hs index db769c2..c7540b2 100644 --- a/assignments/week8/hw/tests/ParserMonadTest.hs +++ b/assignments/week8/hw/tests/ParserMonadTest.hs @@ -1,26 +1,31 @@ -module ParserMonadTest where - -import Test.Tasty (testGroup) -import Test.Tasty.HUnit (assertEqual, assertBool, testCase) -import Test.Tasty.QuickCheck - -import ParserMonad(Parser(Parser),parse,(+++), literal, varParser) - -unitTests = - testGroup - "ParserMonadTest" - [instructorTests - -- TODO: your tests here - ] - -instructorTests = testGroup - "instructorTests" - [testCase "+++ test" $ assertEqual [] (Just (("abc","123"),"")) $ parse ( (literal "abc") +++ (literal "123") ) "abc123", - testCase "+++ test" $ assertEqual [] Nothing $ parse ( (literal "abc") +++ (literal "123") ) "abcd123", - testCase "varParser test" $ assertEqual [] (Just ("abc","")) $ parse varParser "abc" - ] - - --- TODO: your tests here!!! --- TODO: Lots of tests for all the laws! --- TODO: some more tests for: varParser, +++, both success and failure \ No newline at end of file +module ParserMonadTest where + +import Test.Tasty (testGroup) +import Test.Tasty.HUnit (assertEqual, assertBool, testCase) +import Test.Tasty.QuickCheck + +import ParserMonad(Parser(Parser),parse,(+++), literal, varParser) + +unitTests = + testGroup + "ParserMonadTest" + [instructorTests + ,ourTests + -- TODO: your tests here + ] + +instructorTests = testGroup + "instructorTests" + [testCase "+++ test" $ assertEqual [] (Just (("abc","123"),"")) $ parse ( (literal "abc") +++ (literal "123") ) "abc123", + testCase "+++ test" $ assertEqual [] Nothing $ parse ( (literal "abc") +++ (literal "123") ) "abcd123", + testCase "varParser test" $ assertEqual [] (Just ("abc","")) $ parse varParser "abc" + ] + +ourTests = testGroup + "ourTests" + [testCase "+++ test" $ assertEqual [] (Just ("a12", "")) (parse varParser "a12") + ] + +-- TODO: your tests here!!! +-- TODO: Lots of tests for all the laws! +-- TODO: some more tests for: varParser, +++, both success and failure diff --git a/mac-hints.txt b/mac-hints.txt index f1320ef..799e929 100644 --- a/mac-hints.txt +++ b/mac-hints.txt @@ -1,18 +1,18 @@ - -To fix "no-pie" issue: - -Check this link: https://stackoverflow.com/questions/50386787/cabal-install-gcc-failed-in-phase-c-compiler - -Navigate to the directory (might be somewhat different depending on version of Haskell, etc): /Library/Frameworks/GHC.framework/Versions/8.4.2-x86_64/usr/lib/ghc-8.4.2/settings - -Change permissions of "settings" file to Read&Write - -Edit parameter ```C compiler supports -no-pie``` to ```NO```, make sure that you don't accidently insert unicode quotes ```“``` instead of the correct ASCII quote ```"```. - -To fix "--enable-tests" issue: - -Navigate to lab1 directory - -Install necessary packages (see README) - -Type "cabal configure --enable-tests" + +To fix "no-pie" issue: + +Check this link: https://stackoverflow.com/questions/50386787/cabal-install-gcc-failed-in-phase-c-compiler + +Navigate to the directory (might be somewhat different depending on version of Haskell, etc): /Library/Frameworks/GHC.framework/Versions/8.4.2-x86_64/usr/lib/ghc-8.4.2/settings + +Change permissions of "settings" file to Read&Write + +Edit parameter ```C compiler supports -no-pie``` to ```NO```, make sure that you don't accidently insert unicode quotes ```“``` instead of the correct ASCII quote ```"```. + +To fix "--enable-tests" issue: + +Navigate to lab1 directory + +Install necessary packages (see README) + +Type "cabal configure --enable-tests"