Skip to content

Commit

Permalink
Merge pull request #393 from rbasso/anagram-generalize-test-suite
Browse files Browse the repository at this point in the history
anagram: Make the test suite as flexible as possible
  • Loading branch information
petertseng authored Oct 12, 2016
2 parents 7a55278 + 30f4a1d commit 767b32e
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 10 deletions.
22 changes: 22 additions & 0 deletions exercises/anagram/HINTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Hints

To complete this exercise you need to implement the function `anagramsFor`,
that takes a *word* and a group of *words*, returning the ones that are
anagrams of the given *word*.

If it is your first time solving this exercise, it is recommended that you
stick to the provided signature:

```haskell
anagramsFor :: String -> [String] -> [String]
```

Later, it may be a good idea to revisit this problem and play with other data
types and libraries:

- `Text`, from package *text*.
- `Sequence` and `Set`, from package *containers*.
- `MultiSet`, from package *multiset*

The test suite was intentionally designed to accept almost any type signature
that makes sense, so you are encouraged to find the one you think is the best.
3 changes: 3 additions & 0 deletions exercises/anagram/package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ library:
dependencies:
# - foo # List here the packages you
# - bar # want to use in your solution.
- containers
- multiset
- text

tests:
test:
Expand Down
17 changes: 10 additions & 7 deletions exercises/anagram/src/Example.hs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
module Anagram (anagramsFor) where
import Data.List (sort)
import Data.Char (toLower)

anagramsFor :: String -> [String] -> [String]
anagramsFor word = filter (isAnagram . normalize)
import Data.Function (on)
import Data.MultiSet (fromList)
import Data.Set (Set, filter)
import Data.Text (Text, toLower, unpack)
import Prelude hiding (filter)

anagramsFor :: Text -> Set Text -> Set Text
anagramsFor x = filter (\w -> x `isDistinctOf` w && x `isAnagramOf` w)
where
normalize xs = let nxs = map toLower xs in (nxs, sort nxs)
(nw, sw) = normalize word
isAnagram (w, s) = nw /= w && sw == s
isDistinctOf = (/=) `on` toLower
isAnagramOf = (==) `on` fromList . unpack . toLower
12 changes: 9 additions & 3 deletions exercises/anagram/test/Tests.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{-# LANGUAGE RecordWildCards #-}

import Data.Foldable (for_)
import Test.Hspec (Spec, describe, it, shouldBe)
import GHC.Exts (fromList, toList)
import Test.Hspec (Spec, describe, it, shouldMatchList)
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)

import Anagram (anagramsFor)
Expand All @@ -14,9 +15,14 @@ specs = describe "anagram" $
describe "anagramsFor" $ for_ cases test
where

test Case{..} = it description $ expression `shouldBe` expected
test Case{..} = it description $ expression `shouldMatchList` expected
where
expression = anagramsFor subject candidates
expression = map toList
. toList
. anagramsFor (fromList subject)
. fromList
. map fromList
$ candidates

-- Test cases adapted from `exercism/x-common/anagrams.json` on 2016-07-25.

Expand Down

0 comments on commit 767b32e

Please sign in to comment.