Skip to content

Instantly share code, notes, and snippets.

@Nagelfar
Created March 30, 2021 18:35
Show Gist options
  • Save Nagelfar/edabc9650f96d0238316f3c9da1aae20 to your computer and use it in GitHub Desktop.
Save Nagelfar/edabc9650f96d0238316f3c9da1aae20 to your computer and use it in GitHub Desktop.
Phonebook
module Code exposing (..)
type alias Number =
Int
type alias Entry =
{ name : String
, number : String
}
type alias Phonebook =
List Entry
addToPhonebook : Phonebook -> String -> String -> Phonebook
addToPhonebook book name phoneNumber =
{ name = name, number = phoneNumber } :: book
type PhoneBookResult
= Added Phonebook
| Listed String
type Operation
= ShouldAdd String String
| ShouldList (Maybe Number)
parseArguments : String -> Result String Operation
parseArguments arguments =
case arguments |> String.split " " of
[ "add", name, number ] ->
ShouldAdd name number
|> Ok
[ "list" ] ->
ShouldList Nothing
|> Ok
_ ->
Err <| "Could not parse arguments " ++ arguments
listItems : Phonebook -> String
listItems book =
book
|> List.sortBy (\item -> item.name)
|> List.map (\item -> item.name ++ " " ++ item.number)
|> String.join "\n"
phonebook : Phonebook -> Result String Operation -> PhoneBookResult
phonebook book operation =
case operation of
Ok (ShouldAdd name number) ->
addToPhonebook book name number
|> Added
Ok (ShouldList _) ->
book
|> listItems
|> Listed
Err error ->
Debug.todo <| "Error on parsing arguments: " ++ error
parseFileParameters : String -> ( String, String )
parseFileParameters arguments =
( "filename", "remaining arguments" )
writePhonebookToFile : String -> Phonebook -> ()
writePhonebookToFile filename book =
()
loadPhonebookFromFile : String -> Phonebook
loadPhonebookFromFile file =
[]
pbWithPhonebook : String -> Phonebook -> PhoneBookResult
pbWithPhonebook remainingArguments book =
remainingArguments
|> parseArguments
|> phonebook book
pb : String -> String
pb argument =
let
( fileName, remainingArguments ) =
parseFileParameters argument
book =
loadPhonebookFromFile fileName
in
case pbWithPhonebook remainingArguments book of
Added newPhoneBook ->
writePhonebookToFile fileName newPhoneBook
|> (\_ -> "")
Listed listContent ->
listContent
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0"
},
"indirect": {
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.2"
}
},
"test-dependencies": {
"direct": {
"elm-explorations/test": "1.2.2"
},
"indirect": {
"elm/random": "1.0.0"
}
}
}
module Example exposing (..)
import Expect exposing (Expectation)
import Fuzz exposing (Fuzzer, int, list, string)
import Test exposing (..)
import Code exposing (..)
-- Build a program that supports multiple phone booksAccess & store them via a dedicated file parameter
-- Support two primary access methods:
-- Adding one entry to the phone bookAn entry consists of a name and a phone number
-- Return a list of lexical sorted entries from the phone bookSupport skip & limit parameters
-- Rules:
-- Write the phone book with immutable data structures
-- Mutate the state at the last responsible moment
-- Examples:
-- pb foo.txt add Adam +987654
-- pb foo.txt add Christian +4312345
-- pb foo.txt list
-- > Adam +987654
-- > Christian +4312345
-- pb bar.txt add Markus +12334
-- pb bar.txt add Christian +4312345
-- pb bar.txt add Adam +987654
-- pb bar.txt list 1
-- > Christian +4312345
-- > Markus +12334
applyToPhonebook : String -> PhoneBookResult -> PhoneBookResult
applyToPhonebook arguments bookResult =
case bookResult of
Added book ->
book |> pbWithPhonebook arguments
Listed _ ->
Debug.todo "Unexpected result"
suite : Test
suite =
describe "Example 1"
[ describe "guiding tests"
[ test "Add Adam and Christian leads to a sorted output" <|
\_ ->
let
-- arrange
book =
[]
|> Added
|> applyToPhonebook "add Adam +987654"
|> applyToPhonebook "add Christian +4312345"
expected = Listed "Adam +987654\nChristian +4312345"
in
case book of
Added b ->
-- act
b
|> pbWithPhonebook "list"
-- assert
|> Expect.equal expected
_ ->
Expect.fail "expected a phonebook"
]
, test "parsing add with the right arguments" <|
\_ ->
let
result = parseArguments "add Adam +987654"
in
result |> Expect.equal (Ok <| ShouldAdd "Adam" "+987654")
, test "parsing list with the right arguments" <|
\_ ->
let
result = parseArguments "list"
in
result |> Expect.equal (Ok <| ShouldList Nothing)
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment