diff --git a/exercises/diamond/.meta/hints.md b/exercises/diamond/.meta/hints.md new file mode 100644 index 000000000..223b53fa4 --- /dev/null +++ b/exercises/diamond/.meta/hints.md @@ -0,0 +1,39 @@ +## Hints + +You need to implement the `diamond` function which prints a diamond starting at +`A` with the given character at its widest points. You can use the provided +signature if you are unsure about the types, but don't let it restrict your +creativity: + +```haskell +diamond :: Char -> Maybe [String] +``` + +This exercise works with textual data. For historical reasons, Haskell's +`String` type is synonymous with `[Char]`, a list of characters. For more +efficient handling of textual data, the `Text` type can be used. + +As an optional extension to this exercise, you can + +- Read about [string types](https://haskell-lang.org/tutorial/string-types) in + Haskell. +- Add `- text` to your list of dependencies in package.yaml. +- Import `Data.Text` in [the following + way](https://hackernoon.com/4-steps-to-a-better-imports-list-in-haskell-43a3d868273c): + +```haskell +import qualified Data.Text as T +import Data.Text (Text) +``` + +- You can now write e.g. `diamond :: Char -> Maybe [Text]` and refer to + `Data.Text` combinators as e.g. `T.pack`, +- Look up the documentation for + [`Data.Text`](https://hackage.haskell.org/package/text/docs/Data-Text.html), +- You can then replace all occurrences of `String` with `Text` in Diamond.hs: + +```haskell +diamond :: Char -> Maybe [Text] +``` + +This part is entirely optional. diff --git a/exercises/diamond/README.md b/exercises/diamond/README.md index d85616310..88e684e63 100644 --- a/exercises/diamond/README.md +++ b/exercises/diamond/README.md @@ -52,6 +52,47 @@ E·······E ····A···· ``` +## Hints + +You need to implement the `diamond` function which prints a diamond starting at +`A` with the given character at its widest points. You can use the provided +signature if you are unsure about the types, but don't let it restrict your +creativity: + +```haskell +diamond :: Char -> Maybe [String] +``` + +This exercise works with textual data. For historical reasons, Haskell's +`String` type is synonymous with `[Char]`, a list of characters. For more +efficient handling of textual data, the `Text` type can be used. + +As an optional extension to this exercise, you can + +- Read about [string types](https://haskell-lang.org/tutorial/string-types) in + Haskell. +- Add `- text` to your list of dependencies in package.yaml. +- Import `Data.Text` in [the following + way](https://hackernoon.com/4-steps-to-a-better-imports-list-in-haskell-43a3d868273c): + +```haskell +import qualified Data.Text as T +import Data.Text (Text) +``` + +- You can now write e.g. `diamond :: Char -> Maybe [Text]` and refer to + `Data.Text` combinators as e.g. `T.pack`, +- Look up the documentation for + [`Data.Text`](https://hackage.haskell.org/package/text/docs/Data-Text.html), +- You can then replace all occurrences of `String` with `Text` in Diamond.hs: + +```haskell +diamond :: Char -> Maybe [Text] +``` + +This part is entirely optional. + + ## Getting Started diff --git a/exercises/diamond/examples/success-standard/package.yaml b/exercises/diamond/examples/success-standard/package.yaml index 05c4caea2..d2a798394 100644 --- a/exercises/diamond/examples/success-standard/package.yaml +++ b/exercises/diamond/examples/success-standard/package.yaml @@ -15,3 +15,5 @@ tests: - diamond - hspec - QuickCheck + - text + - string-conversions diff --git a/exercises/diamond/package.yaml b/exercises/diamond/package.yaml index b24c564f7..affbac1b5 100644 --- a/exercises/diamond/package.yaml +++ b/exercises/diamond/package.yaml @@ -1,5 +1,5 @@ name: diamond -version: 1.1.0.5 +version: 1.1.0.6 dependencies: - base @@ -20,3 +20,5 @@ tests: - diamond - hspec - QuickCheck + - text + - string-conversions diff --git a/exercises/diamond/test/Tests.hs b/exercises/diamond/test/Tests.hs index 864896a1c..6be83765e 100644 --- a/exercises/diamond/test/Tests.hs +++ b/exercises/diamond/test/Tests.hs @@ -1,14 +1,17 @@ {-# LANGUAGE RecordWildCards #-} - -import Data.Char (isLetter, isPrint, isSpace) -import Data.Foldable (for_) -import Data.List (isSuffixOf) -import Data.Maybe (isJust, isNothing) -import Test.Hspec (Spec, describe, it, shouldBe) -import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith) -import Test.QuickCheck (arbitraryASCIIChar, conjoin, counterexample, - discard, elements, forAll, forAllShrink, Gen, - Property, suchThat, Testable, (===)) +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE FlexibleInstances #-} + +import Data.Char (isLetter, isPrint, isSpace) +import Data.Foldable (for_) +import Data.List (isSuffixOf) +import Data.Maybe (isJust, isNothing) +import Data.String.Conversions (convertString) +import Test.Hspec (Spec, describe, it, shouldBe) +import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith) +import Test.QuickCheck (arbitraryASCIIChar, conjoin, counterexample, + discard, elements, forAll, forAllShrink, Gen, + Property, suchThat, Testable, (===)) import Diamond (diamond) @@ -50,7 +53,7 @@ specs = describe "diamond" $ do where test Case{..} = it description assertion where - assertion = diamond input `shouldBe` Just expected + assertion = (fmap . fmap) convertString (diamond input) `shouldBe` Just expected data Case = Case { description :: String @@ -151,7 +154,7 @@ genAlphaChar :: Gen Char genAlphaChar = elements ['A'..'Z'] genDiamond :: Gen (Maybe [String]) -genDiamond = diamond <$> genAlphaChar +genDiamond = (fmap . fmap . fmap) convertString $ diamond <$> genAlphaChar forAllDiamond :: Testable prop => ([String] -> prop) -> Property forAllDiamond p = forAll genDiamond $ maybe discard p