From 2d9ba1dd20a1310209f3554c034aa25fa9417960 Mon Sep 17 00:00:00 2001 From: milesfrain Date: Sun, 12 Jul 2020 23:32:42 -0700 Subject: [PATCH 1/6] Fix and simplify multi-arg example --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9c9d4af..31f3c7c 100644 --- a/README.md +++ b/README.md @@ -430,9 +430,8 @@ You may occasionally be unable to write `EncodeJson` or `DecodeJson` instances f ```purs data Author - = Following String -- you are subscribed to this author - | NotFollowing String -- you aren't subscribed to this author - | You -- you are the author + = Other String Boolean -- someone else is the author + | You -- you are the author type BlogPost = { title :: String @@ -440,25 +439,27 @@ type BlogPost = } ``` -Our API tells us the author of the blog post as a string and whether we follow them as a boolean. This admits more cases than are actually possible -- you can't follow yourself, for example -- so we are more precise and model an `Author` as a sum type. +Our API tells us the author of the blog post is a `String` and whether we follow them is a `Boolean`. This admits more cases than are actually possible -- you can't follow yourself, for example -- so we are more precise and model an `Author` as a sum type. When our application is running we know who the currently-authenticated user is, and we can use that information to determine the `Author` type. That means we can't decode an `Author` from `Json` alone -- we need more information. In these cases, unfortunately, you can't write an instance of `DecodeJson` for the data type. You can, however, write `decodeJsonAuthor` and use it without the type class. For instance: ```purs -decodeJsonAuthor :: Maybe Username -> Json -> Either JsonDecodeError Author +decodeJsonAuthor :: Maybe Username -> Json -> Either String Author decodeJsonAuthor maybeUsername json = do obj <- decodeJson json author <- obj .: "author" following <- obj .: "following" - pure $ case maybeUsername of + case maybeUsername of -- user is logged in and is the author - Just (Username username) | author == username -> You - -- user is not the author, or no one is logged in, so use the `following` flag - otherwise -> author # if following then Following else NotFollowing + Just (Username username) + | author == username -> Right You + -- user is not the author, or no one is logged in, so use the `following` flag + | otherwise -> Right $ Other author following + Nothing -> Left "Missing Username" -decodeJsonBlogPost :: Maybe Username -> Json -> Either JsonDecodeError BlogPost +decodeJsonBlogPost :: Maybe Username -> Json -> Either String BlogPost decodeJsonBlogPost username json = do obj <- decodeJson json title <- obj .: "title" From 01c3a0a7e85b0a017edb0a3a4a8a515330218e20 Mon Sep 17 00:00:00 2001 From: milesfrain Date: Mon, 13 Jul 2020 10:04:41 -0700 Subject: [PATCH 2/6] Change back to JsonDecodeError --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 31f3c7c..2d45d42 100644 --- a/README.md +++ b/README.md @@ -446,7 +446,7 @@ When our application is running we know who the currently-authenticated user is, In these cases, unfortunately, you can't write an instance of `DecodeJson` for the data type. You can, however, write `decodeJsonAuthor` and use it without the type class. For instance: ```purs -decodeJsonAuthor :: Maybe Username -> Json -> Either String Author +decodeJsonAuthor :: Maybe Username -> Json -> Either JsonDecodeError Author decodeJsonAuthor maybeUsername json = do obj <- decodeJson json author <- obj .: "author" @@ -457,9 +457,9 @@ decodeJsonAuthor maybeUsername json = do | author == username -> Right You -- user is not the author, or no one is logged in, so use the `following` flag | otherwise -> Right $ Other author following - Nothing -> Left "Missing Username" + Nothing -> Left $ Named "Username" MissingValue -decodeJsonBlogPost :: Maybe Username -> Json -> Either String BlogPost +decodeJsonBlogPost :: Maybe Username -> Json -> Either JsonDecodeError BlogPost decodeJsonBlogPost username json = do obj <- decodeJson json title <- obj .: "title" From 5a5f0491ddf8a3f7354582abbbf487db01c6780f Mon Sep 17 00:00:00 2001 From: milesfrain Date: Mon, 13 Jul 2020 13:35:38 -0700 Subject: [PATCH 3/6] Fix logic --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 2d45d42..b82831f 100644 --- a/README.md +++ b/README.md @@ -429,9 +429,12 @@ encodeUserAsArray user = encodeJson [ user.uuid, user.name ] You may occasionally be unable to write `EncodeJson` or `DecodeJson` instances for a data type because it requires more information than just `Json` as its argument. For instance, consider this pair of types: ```purs +newtype Following + = Following Boolean + data Author - = Other String Boolean -- someone else is the author - | You -- you are the author + = Other String Following -- someone else is the author + | You -- you are the author type BlogPost = { title :: String @@ -455,9 +458,8 @@ decodeJsonAuthor maybeUsername json = do -- user is logged in and is the author Just (Username username) | author == username -> Right You - -- user is not the author, or no one is logged in, so use the `following` flag - | otherwise -> Right $ Other author following - Nothing -> Left $ Named "Username" MissingValue + -- user is not the author, or no one is logged in, so use the `following` flag + _ -> Right $ Other author $ Following following decodeJsonBlogPost :: Maybe Username -> Json -> Either JsonDecodeError BlogPost decodeJsonBlogPost username json = do From 8b415e82a13b62f64d0eda35dec218dfa2e9b532 Mon Sep 17 00:00:00 2001 From: milesfrain Date: Mon, 13 Jul 2020 13:46:49 -0700 Subject: [PATCH 4/6] Closer match to original --- README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b82831f..f64ec0f 100644 --- a/README.md +++ b/README.md @@ -429,12 +429,10 @@ encodeUserAsArray user = encodeJson [ user.uuid, user.name ] You may occasionally be unable to write `EncodeJson` or `DecodeJson` instances for a data type because it requires more information than just `Json` as its argument. For instance, consider this pair of types: ```purs -newtype Following - = Following Boolean - data Author - = Other String Following -- someone else is the author - | You -- you are the author + = Following String -- you are subscribed to this author + | NotFollowing String -- you aren't subscribed to this author + | You -- you are the author type BlogPost = { title :: String @@ -456,10 +454,9 @@ decodeJsonAuthor maybeUsername json = do following <- obj .: "following" case maybeUsername of -- user is logged in and is the author - Just (Username username) - | author == username -> Right You + Just (Username username) | author == username -> Right You -- user is not the author, or no one is logged in, so use the `following` flag - _ -> Right $ Other author $ Following following + _ -> if following then Following else NotFollowing $ author decodeJsonBlogPost :: Maybe Username -> Json -> Either JsonDecodeError BlogPost decodeJsonBlogPost username json = do From 108748b43884602bac7ff834095855be6639a5ec Mon Sep 17 00:00:00 2001 From: milesfrain Date: Mon, 13 Jul 2020 13:51:01 -0700 Subject: [PATCH 5/6] purs ide issues. Assumed previous version built --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f64ec0f..76457cb 100644 --- a/README.md +++ b/README.md @@ -452,11 +452,11 @@ decodeJsonAuthor maybeUsername json = do obj <- decodeJson json author <- obj .: "author" following <- obj .: "following" - case maybeUsername of + pure $ case maybeUsername of -- user is logged in and is the author - Just (Username username) | author == username -> Right You + Just (Username username) | author == username -> You -- user is not the author, or no one is logged in, so use the `following` flag - _ -> if following then Following else NotFollowing $ author + _ -> author # if following then Following else NotFollowing decodeJsonBlogPost :: Maybe Username -> Json -> Either JsonDecodeError BlogPost decodeJsonBlogPost username json = do From 7f3e0a80e3c88f34642eb72ff318b1c5943358a5 Mon Sep 17 00:00:00 2001 From: milesfrain Date: Mon, 13 Jul 2020 14:23:48 -0700 Subject: [PATCH 6/6] tells -> sends --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 76457cb..a2dcac0 100644 --- a/README.md +++ b/README.md @@ -440,7 +440,7 @@ type BlogPost = } ``` -Our API tells us the author of the blog post is a `String` and whether we follow them is a `Boolean`. This admits more cases than are actually possible -- you can't follow yourself, for example -- so we are more precise and model an `Author` as a sum type. +Our API sends us the author of the blog post as a string and whether we follow them as a boolean. This admits more cases than are actually possible -- you can't follow yourself, for example -- so we are more precise and model an `Author` as a sum type. When our application is running we know who the currently-authenticated user is, and we can use that information to determine the `Author` type. That means we can't decode an `Author` from `Json` alone -- we need more information.