Skip to content

Commit 53ac94d

Browse files
author
Răzvan C. Rădulescu
authored
Remove unsafePartial regex (#248)
* Remove unsafePartial code and fix regression I mistakingly changed the name from Solutions.* to MySolutions.* while working on the commit that fixed the addressbook applicative. This commit also fixes this rename issue. * Update text and remove extra error info Error info is already captured by the error message returned from javascript
1 parent 7eaf36d commit 53ac94d

File tree

7 files changed

+37
-49
lines changed

7 files changed

+37
-49
lines changed

exercises/chapter10/src/Data/AddressBook/Validation.purs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import Data.String.Regex (Regex, test, regex)
99
import Data.String.Regex.Flags (noFlags)
1010
import Data.Traversable (traverse)
1111
import Data.Validation.Semigroup (V, invalid, toEither)
12-
import Partial.Unsafe (unsafePartial)
1312

1413
type Errors
1514
= Array String
@@ -29,16 +28,14 @@ lengthIs field len value | length value /= len =
2928
invalid [ "Field '" <> field <> "' must have length " <> show len ]
3029
lengthIs _ _ value = pure value
3130

32-
phoneNumberRegex :: Regex
33-
phoneNumberRegex =
34-
unsafePartial case regex "^\\d{3}-\\d{3}-\\d{4}$" noFlags of
35-
Right r -> r
31+
phoneNumberRegex :: Either String Regex
32+
phoneNumberRegex = regex "^\\d{3}-\\d{3}-\\d{4}$" noFlags
3633

37-
matches :: String -> Regex -> String -> V Errors String
38-
matches _ regex value | test regex value =
39-
pure value
40-
matches field _ _ =
41-
invalid [ "Field '" <> field <> "' did not match the required format" ]
34+
matches :: String -> Either String Regex -> String -> V Errors String
35+
matches _ (Right regex) value | test regex value
36+
= pure value
37+
matches _ (Left error) _ = invalid [ error ]
38+
matches field _ _ = invalid [ "Field '" <> field <> "' did not match the required format" ]
4239

4340
validateAddress :: Address -> V Errors Address
4441
validateAddress a =

exercises/chapter10/test/Main.purs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module Test.Main where
33
import Prelude
44
import Test.Examples
55
import Test.MySolutions
6+
67
import Control.Monad.Free (Free)
78
import Data.Argonaut (decodeJson, encodeJson)
89
import Data.Either (Either(..), isLeft)

exercises/chapter7/src/Data/AddressBook/Validation.purs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import Data.String.Regex (Regex, test, regex)
88
import Data.String.Regex.Flags (noFlags)
99
import Data.Traversable (traverse)
1010
import Data.Validation.Semigroup (V, invalid)
11-
import Partial.Unsafe (unsafePartial)
1211

1312
-----------------
1413
-- Some simple early examples returning `Either` instead of `V`:
@@ -65,18 +64,16 @@ lengthIs _ _ value = pure value
6564
-- ANCHOR_END: lengthIs
6665

6766
-- ANCHOR: phoneNumberRegex
68-
phoneNumberRegex :: Regex
69-
phoneNumberRegex =
70-
unsafePartial case regex "^\\d{3}-\\d{3}-\\d{4}$" noFlags of
71-
Right r -> r
67+
phoneNumberRegex :: Either String Regex
68+
phoneNumberRegex = regex "^\\d{3}-\\d{3}-\\d{4}$" noFlags
7269
-- ANCHOR_END: phoneNumberRegex
7370

7471
-- ANCHOR: matches
75-
matches :: String -> Regex -> String -> V Errors String
76-
matches _ regex value | test regex value =
77-
pure value
78-
matches field _ _ =
79-
invalid [ "Field '" <> field <> "' did not match the required format" ]
72+
matches :: String -> Either String Regex -> String -> V Errors String
73+
matches _ (Right regex) value | test regex value
74+
= pure value
75+
matches _ (Left error) _ = invalid [ error ]
76+
matches field _ _ = invalid [ "Field '" <> field <> "' did not match the required format" ]
8077
-- ANCHOR_END: matches
8178

8279
-- ANCHOR: validateAddress

exercises/chapter7/test/Main.purs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module Test.Main where
33
import Prelude
44
import Test.MySolutions
55
import Test.NoPeeking.Solutions -- Note to reader: Delete this line
6+
67
import Control.Monad.Writer (runWriter, tell)
78
import Data.AddressBook (PhoneType(..), address, phoneNumber)
89
import Data.Array ((..))
@@ -102,8 +103,8 @@ Note to reader: Delete this line to expand comment block -}
102103
let
103104
stateTest str exp =
104105
test (show str) do
105-
Assert.equal exp
106-
$ R.test stateRegex str
106+
Assert.equal (Right exp)
107+
$ R.test <$> stateRegex <*> Right str
107108
stateTest "CA" true
108109
stateTest "Ca" true
109110
stateTest "C" false
@@ -113,8 +114,8 @@ Note to reader: Delete this line to expand comment block -}
113114
let
114115
nonEmptyTest str exp =
115116
test (show str) do
116-
Assert.equal exp
117-
$ R.test nonEmptyRegex str
117+
Assert.equal (Right exp)
118+
$ R.test <$> nonEmptyRegex <*> Right str
118119
nonEmptyTest "Houston" true
119120
nonEmptyTest "My Street" true
120121
nonEmptyTest "Ñóñá" true

exercises/chapter7/test/no-peeking/Solutions.purs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Prelude
44
import Control.Apply (lift2)
55
import Data.AddressBook (Address, PhoneNumber, address)
66
import Data.AddressBook.Validation (Errors, matches, nonEmpty, validateAddress, validatePhoneNumbers)
7-
import Data.Either (Either(..))
7+
import Data.Either (Either)
88
import Data.Generic.Rep (class Generic)
99
import Data.Generic.Rep.Eq (genericEq)
1010
import Data.Generic.Rep.Show (genericShow)
@@ -13,7 +13,6 @@ import Data.String.Regex (Regex, regex)
1313
import Data.String.Regex.Flags (noFlags)
1414
import Data.Traversable (class Foldable, class Traversable, foldMap, foldl, foldr, sequence, traverse)
1515
import Data.Validation.Semigroup (V)
16-
import Partial.Unsafe (unsafePartial)
1716

1817
{-| Exercise Group 1 -}
1918
-- Exercise 1
@@ -50,24 +49,20 @@ combineMaybe _ = pure Nothing
5049

5150
{-| Exercise Group 2 -}
5251
-- Exercise 1
53-
stateRegex :: Regex
54-
stateRegex =
55-
unsafePartial case regex "^[a-zA-Z]{2}$" noFlags of
56-
Right r -> r
52+
stateRegex :: Either String Regex
53+
stateRegex = regex "^[a-zA-Z]{2}$" noFlags
5754

5855
-- Exercise 2
59-
nonEmptyRegex :: Regex
60-
nonEmptyRegex =
61-
unsafePartial case regex "[^\\s]$" noFlags of
62-
Right r -> r
56+
nonEmptyRegex :: Either String Regex
57+
nonEmptyRegex = regex "[^\\s]$" noFlags
6358

6459
-- Exercise 3
6560
validateAddressImproved :: Address -> V Errors Address
6661
validateAddressImproved a =
6762
address
68-
<$> (matches "Street" nonEmptyRegex a.street *> pure a.street)
69-
<*> (matches "City" nonEmptyRegex a.city *> pure a.city)
70-
<*> (matches "State" stateRegex a.state *> pure a.state)
63+
<$> matches "Street" nonEmptyRegex a.street
64+
<*> matches "City" nonEmptyRegex a.city
65+
<*> matches "State" stateRegex a.state
7166

7267
{-| Exercise Group 3 -}
7368
-- Exercise 1

exercises/chapter8/src/Data/AddressBook/Validation.purs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import Data.String.Regex (Regex, test, regex)
99
import Data.String.Regex.Flags (noFlags)
1010
import Data.Traversable (traverse)
1111
import Data.Validation.Semigroup (V, invalid, toEither)
12-
import Partial.Unsafe (unsafePartial)
1312

1413
type Errors
1514
= Array String
@@ -29,16 +28,14 @@ lengthIs field len value | length value /= len =
2928
invalid [ "Field '" <> field <> "' must have length " <> show len ]
3029
lengthIs _ _ value = pure value
3130

32-
phoneNumberRegex :: Regex
33-
phoneNumberRegex =
34-
unsafePartial case regex "^\\d{3}-\\d{3}-\\d{4}$" noFlags of
35-
Right r -> r
31+
phoneNumberRegex :: Either String Regex
32+
phoneNumberRegex = regex "^\\d{3}-\\d{3}-\\d{4}$" noFlags
3633

37-
matches :: String -> Regex -> String -> V Errors String
38-
matches _ regex value | test regex value =
39-
pure value
40-
matches field _ _ =
41-
invalid [ "Field '" <> field <> "' did not match the required format" ]
34+
matches :: String -> Either String Regex -> String -> V Errors String
35+
matches _ (Right regex) value | test regex value
36+
= pure value
37+
matches _ (Left error) _ = invalid [ error ]
38+
matches field _ _ = invalid [ "Field '" <> field <> "' did not match the required format" ]
4239

4340
validateAddress :: Address -> V Errors Address
4441
validateAddress a =

text/chapter7.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,8 +537,8 @@ invalid (["Field 'Number' did not match the required format"])
537537

538538
## Exercises
539539

540-
1. (Easy) Write a regular expression `stateRegex :: Regex` to check that a string only contains two alphabetic characters. _Hint_: see the source code for `phoneNumberRegex`.
541-
1. (Medium) Write a regular expression `nonEmptyRegex :: Regex` to check that a string is not entirely whitespace. _Hint_: If you need help developing this regex expression, check out [RegExr](https://regexr.com) which has a great cheatsheet and interactive test environment.
540+
1. (Easy) Write a regular expression `stateRegex :: Either String Regex` to check that a string only contains two alphabetic characters. _Hint_: see the source code for `phoneNumberRegex`.
541+
1. (Medium) Write a regular expression `nonEmptyRegex :: Either String Regex` to check that a string is not entirely whitespace. _Hint_: If you need help developing this regex expression, check out [RegExr](https://regexr.com) which has a great cheatsheet and interactive test environment.
542542
1. (Medium) Write a function `validateAddressImproved` that is similar to `validateAddress`, but uses the above `stateRegex` to validate the `state` field and `nonEmptyRegex` to validate the `street` and `city` fields. _Hint_: see the source for `validatePhoneNumber` for an example of how to use `matches`.
543543

544544
## Traversable Functors

0 commit comments

Comments
 (0)