aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Sucan <jan@jansucan.com>2023-03-16 20:05:13 +0100
committerJan Sucan <jan@jansucan.com>2023-03-16 20:05:13 +0100
commit03a11303d19993023a6b75ef639624befadfdf5a (patch)
treee542e8e9df750f6ec1764a02f7cff7d0c89b7088
parent82e61723ec378cefd56b5b351340b3d33bc490fc (diff)
4_a_2: Add solution
-rw-r--r--README.md2
-rw-r--r--ch04/4_a_2.hs25
2 files changed, 26 insertions, 1 deletions
diff --git a/README.md b/README.md
index e330d0f..0cc741e 100644
--- a/README.md
+++ b/README.md
@@ -69,7 +69,7 @@ more visible in the list the first exercise of a group is in bold italics.
| 3_b_11 | yes, in 3_b_9 | | |
| 3_b_12 | yes, in 3_b_9 | | |
| **_4_a_1_** | yes | 84 | 4. Functional programming |
-| 4_a_2 | | | |
+| 4_a_2 | yes | | |
| 4_a_3 | | | |
| 4_a_4 | | | |
| **_4_b_1_** | | 97 | |
diff --git a/ch04/4_a_2.hs b/ch04/4_a_2.hs
new file mode 100644
index 0000000..9a14c34
--- /dev/null
+++ b/ch04/4_a_2.hs
@@ -0,0 +1,25 @@
+-- Write a function splitWith that acts similarly to words, but takes a
+-- predicate and a list of any type, and splits its input list on every element
+-- for which the predicate returns False.
+--
+-- -- file: ch04/ch04.exercises.hs
+-- splitWith :: (a -> Bool) -> [a] -> [[a]]
+
+safeTail :: [a] -> [a]
+safeTail [] = []
+safeTail xs = tail xs
+
+splitWith :: (a -> Bool) -> [a] -> [[a]]
+splitWith f [] = []
+splitWith f xs = if not (null first)
+ then first:splitRest
+ else splitRest
+ where (first, suffix) = span f xs
+ rest = safeTail suffix
+ splitRest = splitWith f rest
+
+-- ghci> :l 4_a_2.hs
+-- [1 of 1] Compiling Main ( 4_a_2.hs, interpreted )
+-- Ok, one module loaded.
+-- ghci> splitWith even [2, 1, 4, 4, 3, 3, 6, 6, 6]
+-- [[2],[4,4],[6,6,6]]