From 0313e26d28ae3253dc57426314b2772856185e82 Mon Sep 17 00:00:00 2001 From: Miles Frain Date: Tue, 3 Nov 2020 12:39:31 -0800 Subject: [PATCH 1/2] Ch6 Clarify Action exercises --- exercises/chapter6/test/Main.purs | 4 ++- .../chapter6/test/no-peeking/Solutions.purs | 28 +++++++------------ text/chapter6.md | 19 +++++++++++-- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/exercises/chapter6/test/Main.purs b/exercises/chapter6/test/Main.purs index 0d8680f7..a0335157 100644 --- a/exercises/chapter6/test/Main.purs +++ b/exercises/chapter6/test/Main.purs @@ -1,7 +1,9 @@ module Test.Main where import Prelude +import Test.MySolutions import Test.NoPeeking.Solutions -- Note to reader: Delete this line + import Data.Foldable (foldMap, foldl, foldr) import Data.Hashable (hash) import Data.List (List(..), (:)) @@ -166,7 +168,7 @@ Note to reader: Delete this line to expand comment block -} Assert.equal (act m1 (act m2 a)) $ act (m1 <> m2) a test "Multiply Array String append concrete" do - Assert.equal + Assert.equal [ "foofoofoofoofoofoofoofoofoofoofoofoo" , "barbarbarbarbarbarbarbarbarbarbarbar" , "bazbazbazbazbazbazbazbazbazbazbazbaz" diff --git a/exercises/chapter6/test/no-peeking/Solutions.purs b/exercises/chapter6/test/no-peeking/Solutions.purs index bb52b6b6..df0fcc48 100644 --- a/exercises/chapter6/test/no-peeking/Solutions.purs +++ b/exercises/chapter6/test/no-peeking/Solutions.purs @@ -89,16 +89,14 @@ instance semigroupMultiply :: Semigroup Multiply where instance monoidMultiply :: Monoid Multiply where mempty = Multiply 1 -instance actionMultiply :: Action Multiply Int where +instance actionMultiplyInt :: Action Multiply Int where act (Multiply n) m = n * m -instance showMultiply :: Show Multiply where - show (Multiply n) = "Multiply " <> show n +-- These may also be written manualy +derive newtype instance showMultiply :: Show Multiply +derive newtype instance eqMultiply :: Eq Multiply -instance eqMultiply :: Eq Multiply where - eq (Multiply n) (Multiply m) = n == m - -instance repeatAction :: Action Multiply String where +instance actionMultiplyString :: Action Multiply String where act (Multiply n) s = power s n instance actionArray :: Action m a => Action m (Array a) where @@ -113,17 +111,11 @@ newtype Self m instance actionSelf :: Monoid m => Action m (Self m) where act m1 (Self m2) = Self (m1 <> m2) -instance eqSelf :: Eq m => Eq (Self m) where - eq (Self m1) (Self m2) = m1 == m2 - -instance showSelf :: Show m => Show (Self m) where - show (Self m) = "Self " <> show m - -instance semigroupSelf :: Semigroup m => Semigroup (Self m) where - append (Self a) (Self b) = Self (a <> b) - -instance monoidSelf :: Monoid m => Monoid (Self m) where - mempty = Self mempty +-- These may also be written manualy +derive newtype instance showSelf :: Show m => Show (Self m) +derive newtype instance eqSelf :: Eq m => Eq (Self m) +derive newtype instance semigroupSelf :: Semigroup m => Semigroup (Self m) +derive newtype instance monoidSelf :: Monoid m => Monoid (Self m) instance repeatActionMultSelf :: Action (Self Multiply) Int where act (Self (Multiply m)) s = m * s diff --git a/text/chapter6.md b/text/chapter6.md index 9d769df9..e9b6f1f4 100644 --- a/text/chapter6.md +++ b/text/chapter6.md @@ -635,6 +635,7 @@ Another reason to define a superclass relationship is in the case where there is ## Exercises 1. (Medium) Define a partial function `unsafeMaximum :: Partial => Array Int -> Int` which finds the maximum of a non-empty array of integers. Test out your function in PSCi using `unsafePartial`. _Hint_: Use the `maximum` function from `Data.Foldable`. + 1. (Medium) The `Action` class is a multi-parameter type class which defines an action of one type on another: ```haskell @@ -661,20 +662,32 @@ Another reason to define a superclass relationship is in the case where there is mempty = Multiply 1 ``` - This monoid acts on strings by repeating an input string some number of times. Write an instance which implements this action: + Write an instance which implements this action: + + ```haskell + instance actionMultiplyInt :: Action Multiply Int + ``` + Does this instance satisfy the laws listed above? + +1. (Medium) Write an `Action` instance which repeats an input string some number of times: ```haskell - instance repeatAction :: Action Multiply String + instance actionMultiplyString :: Action Multiply String ``` - _Hint_: Search Pursuit for a helper-function with the signature `String -> Int -> String`. Note that `String` might appear as a more generic type. + _Hint_: Search Pursuit for a helper-function with the signature [`String -> Int -> String`](https://pursuit.purescript.org/search?q=String%20-%3E%20Int%20-%3E%20String). Note that `String` might appear as a more generic type (such as `Monoid`). Does this instance satisfy the laws listed above? + 1. (Medium) Write an instance `Action m a => Action m (Array a)`, where the action on arrays is defined by acting on each array element independently. + 1. (Difficult) Given the following newtype, write an instance for `Action m (Self m)`, where the monoid `m` acts on itself using `append`: ```haskell newtype Self m = Self m ``` + + _Note_: The testing framework requires `Show` and `Eq` instances for the `Self` and `Multiply` types. You may either write these instances manually, or let the compiler handle this for you with [`derive newtype instance`](https://github.com/purescript/documentation/blob/master/language/Type-Classes.md#type-class-deriving) shorthand. + 1. (Difficult) Should the arguments of the multi-parameter type class `Action` be related by some functional dependency? Why or why not? _Note_: There is no test for this exercise. ## A Type Class for Hashes From acf4026e0bbef4e1e2f84d2e4649c40bbc506040 Mon Sep 17 00:00:00 2001 From: Miles Frain Date: Thu, 5 Nov 2020 15:07:07 -0800 Subject: [PATCH 2/2] update link, remove comment --- exercises/chapter6/test/no-peeking/Solutions.purs | 3 --- text/chapter6.md | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/exercises/chapter6/test/no-peeking/Solutions.purs b/exercises/chapter6/test/no-peeking/Solutions.purs index df0fcc48..b25d3d8b 100644 --- a/exercises/chapter6/test/no-peeking/Solutions.purs +++ b/exercises/chapter6/test/no-peeking/Solutions.purs @@ -105,9 +105,6 @@ instance actionArray :: Action m a => Action m (Array a) where newtype Self m = Self m --- Why is Monoid constraint required here? --- Seems like this is already specified by Action class ---instance actionSelf :: Action m (Self m) where instance actionSelf :: Monoid m => Action m (Self m) where act m1 (Self m2) = Self (m1 <> m2) diff --git a/text/chapter6.md b/text/chapter6.md index e9b6f1f4..21ae6d10 100644 --- a/text/chapter6.md +++ b/text/chapter6.md @@ -686,7 +686,7 @@ Another reason to define a superclass relationship is in the case where there is newtype Self m = Self m ``` - _Note_: The testing framework requires `Show` and `Eq` instances for the `Self` and `Multiply` types. You may either write these instances manually, or let the compiler handle this for you with [`derive newtype instance`](https://github.com/purescript/documentation/blob/master/language/Type-Classes.md#type-class-deriving) shorthand. + _Note_: The testing framework requires `Show` and `Eq` instances for the `Self` and `Multiply` types. You may either write these instances manually, or let the compiler handle this for you with [`derive newtype instance`](https://github.com/purescript/documentation/blob/master/language/Type-Classes.md#derive-from-newtype) shorthand. 1. (Difficult) Should the arguments of the multi-parameter type class `Action` be related by some functional dependency? Why or why not? _Note_: There is no test for this exercise.