Skip to content

Instantly share code, notes, and snippets.

@davenportw15
Created July 25, 2015 05:14
Show Gist options
  • Save davenportw15/e4deee8654f65734fb7f to your computer and use it in GitHub Desktop.
Save davenportw15/e4deee8654f65734fb7f to your computer and use it in GitHub Desktop.
module EvaluateSandwich
( SandwichComponent
, Sandwich
, validateSandwich
, indicesSeparated
) where
import Data.List (elemIndices)
-- | Components of a sandwich
-- Allows for arbitrary fillings through `Filling String`
data SandwichComponent
= Bread
| Meat
| Cheese
| Filling String
deriving (Eq, Show, Read)
-- | A sandwich is a list of sandwich components
type Sandwich = [SandwichComponent]
-- | Validates that a sandwich has at least
-- one filling between two slices of bread.
-- Valid sandwiches can contain components
-- outside of these two slices of bread
-- (This includes other slices of bread)
validateSandwich :: Sandwich -> Bool
validateSandwich = indicesSeparated . elemIndices Bread
-- | Validates that at least two indices are
-- separated by at least one index
indicesSeparated :: (Integral a) => [a] -> Bool
indicesSeparated indices
| length indices < 2 = False
| otherwise =
let first : second : rest = indices in
second - first > 1 || indicesSeparated (second : rest)
@davenportw15
Copy link
Author

Example usage:

validateSandwich [Bread, Cheese, Filling "Tomato", Meat, Bread]
  => True
validateSandwich [Bread, Filling "Lettuce", Meat, Cheese, Bread, Cheese]
  => True
validateSandwich [Cheese, Cheese, Cheese]
  => False (but appetizing)
validateSandwich [Bread, Bread, Cheese]
  => False

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment