Skip to content

Commit 218530a

Browse files
tests for Monad Comprehensions and backtracking (#374)
* tests for Monad Comprehensions and backtracking * added dependency
1 parent 9ed573e commit 218530a

File tree

4 files changed

+44
-4
lines changed

4 files changed

+44
-4
lines changed

Diff for: exercises/chapter11/spago.dhall

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ You can edit this file as you like.
44
-}
55
{ name = "my-project"
66
, dependencies =
7-
[ "console"
7+
[ "arrays"
8+
, "console"
89
, "control"
910
, "effect"
1011
, "either"

Diff for: exercises/chapter11/test/Main.purs

+28-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module Test.Main where
22

3-
import Prelude
3+
import Prelude (Unit, discard, ($), (<>))
44

55
import Test.MySolutions
66
import Test.NoPeeking.Solutions -- Note to reader: Delete this line
@@ -102,5 +102,32 @@ Note to reader: Delete this line to expand comment block -}
102102
indent' $ do
103103
line' "I am even more indented"
104104

105+
suite "Exercises Group - Monad Comprehensions/backtracking" do
106+
suite "parser" do
107+
let
108+
runParser p s = unwrap $ runExceptT $ runWriterT $ runStateT p s
109+
test "should parse as followed by bs" do
110+
Assert.equal (Right (Tuple (Tuple "aaabb" "cde") [
111+
"The state is aaabbcde",
112+
"The state is aabbcde",
113+
"The state is abbcde",
114+
"The state is bbcde",
115+
"The state is bcde"]))
116+
$ runParser asFollowedByBs "aaabbcde"
117+
test "should fail if first is not a" do
118+
Assert.equal (Left ["Could not parse"])
119+
$ runParser asFollowedByBs "bfoobar"
120+
test "should parse as and bs" do
121+
Assert.equal (Right (Tuple (Tuple "babbaa" "cde") [
122+
"The state is babbaacde",
123+
"The state is abbaacde",
124+
"The state is bbaacde",
125+
"The state is baacde",
126+
"The state is aacde",
127+
"The state is acde"]))
128+
$ runParser asOrBs "babbaacde"
129+
test "should fail if first is not a or b" do
130+
Assert.equal (Left ["Could not parse","Could not parse"])
131+
$ runParser asOrBs "foobar"
105132
{- Note to reader: Delete this line to expand comment block
106133
-}

Diff for: exercises/chapter11/test/no-peeking/Solutions.purs

+12
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ module Test.NoPeeking.Solutions where
22

33
import Prelude
44

5+
import Control.Alt ((<|>))
56
import Control.Monad.Except (ExceptT, throwError)
67
import Control.Monad.Reader (Reader, ReaderT, ask, lift, local, runReader, runReaderT)
78
import Control.Monad.State (State, StateT, get, put, execState, modify_)
89
import Control.Monad.Writer (Writer, WriterT, tell, runWriter, execWriterT)
10+
import Data.Array (some)
11+
import Data.Foldable (fold)
912
import Data.Identity (Identity)
1013
import Data.Maybe (Maybe(..))
1114
import Data.Monoid (power)
@@ -112,3 +115,12 @@ indent' = local $ (+) 1
112115

113116
render' :: Doc' -> String
114117
render' doct = joinWith "\n" $ unwrap $ runReaderT (execWriterT doct) 0
118+
119+
asFollowedByBs :: Parser String
120+
asFollowedByBs = do
121+
as <- some $ string "a"
122+
bs <- some $ string "b"
123+
pure $ fold $ as <> bs
124+
125+
asOrBs :: Parser String
126+
asOrBs = fold <$> some (string "a" <|> string "b")

Diff for: text/chapter11.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -731,8 +731,8 @@ Again, this illustrates the power of reusability that monad transformers bring -
731731
## Exercises
732732

733733
1. (Easy) Remove the calls to the `lift` function from your implementation of the `string` parser. Verify that the new implementation type checks, and convince yourself that it should.
734-
1. (Medium) Use your `string` parser with the `many` combinator to write a parser which recognizes strings consisting of several copies of the string `"a"` followed by several copies of the string `"b"`.
735-
1. (Medium) Use the `<|>` operator to write a parser which recognizes strings of the letters `a` or `b` in any order.
734+
1. (Medium) Use your `string` parser with the `many` combinator to write a parser `asFollowedByBs` which recognizes strings consisting of several copies of the string `"a"` followed by several copies of the string `"b"`.
735+
1. (Medium) Use the `<|>` operator to write a parser `asOrBs` which recognizes strings of the letters `a` or `b` in any order.
736736
1. (Difficult) The `Parser` monad might also be defined as follows:
737737

738738
```haskell

0 commit comments

Comments
 (0)