1
1
mirror of https://github.com/qfpl/applied-fp-course.git synced 2024-11-26 06:38:40 +03:00

modFieldLabel in level05+ is 'almost' just the identity.

But that was largely due to missing field prefixes in the Comment record for
that level. Field prefixes added back in and added some doctests and changed the
wording for that section to explain a bit more of what is going on.
This commit is contained in:
Sean Chalmers 2017-10-05 14:35:39 +10:00
parent f63d3ee483
commit 94711343b6
6 changed files with 65 additions and 31 deletions

View File

@ -49,13 +49,29 @@ newtype CommentId = CommentId Int
deriving (Eq, Show, ToJSON)
data Comment = Comment
{ commentId :: CommentId
, topic :: Topic
, body :: CommentText
, time :: UTCTime
{ commentId :: CommentId
, commentTopic :: Topic
, commentBody :: CommentText
, commentTime :: UTCTime
}
deriving ( Show, Generic )
-- Strip the prefix (which may fail if the prefix isn't present), fall
-- back to the original label if need be, then camel-case the name.
-- | modFieldLabel
-- >>> modFieldLabel "commentId"
-- "id"
-- >>> modFieldLabel "topic"
-- "topic"
-- >>> modFieldLabel ""
-- ""
modFieldLabel
:: String
-> String
modFieldLabel =
error "modFieldLabel not implemented"
instance ToJSON Comment where
-- This is one place where we can take advantage of our `Generic` instance.
-- Aeson already has the encoding functions written for anything that
@ -65,18 +81,12 @@ instance ToJSON Comment where
where
-- These options let us make some minor adjustments to how Aeson treats
-- our type. Our only adjustment is to alter the field names a little, to
-- remove the 'comment' prefix and camel case what is left of the name.
-- This accepts any 'String -> String' function but it's good to keep the
-- modifications simple.
-- remove the 'comment' prefix and use an Aeson function to handle the
-- rest of the name. This accepts any 'String -> String' function but it's
-- wise to keep the modifications simple.
opts = A.defaultOptions
{ A.fieldLabelModifier = modFieldLabel
}
-- Strip the prefix (which may fail if the prefix isn't present), fall
-- back to the original label if need be, then camel-case the name.
modFieldLabel
:: String
-> String
modFieldLabel = error "modFieldLabel not implemented"
-- For safety we take our stored `DbComment` and try to construct a `Comment`
-- that we would be okay with showing someone. However unlikely it may be, this

View File

@ -7,4 +7,5 @@ main = doctest
[ "-isrc"
, "src/FirstApp/Conf.hs"
, "src/FirstApp/DB.hs"
, "src/FirstApp/Types.hs"
]

View File

@ -51,6 +51,24 @@ data Comment = Comment
-- Generic has been added to our deriving list.
deriving ( Show, Generic )
-- Strip the prefix (which may fail if the prefix isn't present), fall
-- back to the original label if need be, then camel-case the name.
-- | modFieldLabel
-- >>> modFieldLabel "commentId"
-- "id"
-- >>> modFieldLabel "topic"
-- "topic"
-- >>> modFieldLabel ""
-- ""
modFieldLabel
:: String
-> String
modFieldLabel l =
A.camelTo2 '_'
. fromMaybe l
$ stripPrefix "comment" l
instance ToJSON Comment where
-- This is one place where we can take advantage of our Generic instance. Aeson
-- already has the encoding functions written for anything that implements the
@ -60,19 +78,13 @@ instance ToJSON Comment where
where
-- These options let us make some minor adjustments to how Aeson treats
-- our type. Our only adjustment is to alter the field names a little, to
-- remove the 'comment' prefix and camel case what is left of the name.
-- This accepts any 'String -> String' function but it's good to keep the
-- modifications simple.
-- remove the 'comment' prefix and use an Aeson function to handle the
-- rest of the name. This accepts any 'String -> String' function but it's
-- wise to keep the modifications simple.
opts = A.defaultOptions
{ A.fieldLabelModifier = modFieldLabel
}
-- Strip the prefix (which may fail if the prefix isn't present), fall
-- back to the original label if need be, then camel-case the name.
modFieldLabel l =
A.camelTo2 '_' . fromMaybe l
$ stripPrefix "comment" l
-- For safety we take our stored DbComment and try to construct a Comment that
-- we would be okay with showing someone. However unlikely it may be, this is a
-- nice method for separating out the back and front end of a web app and

View File

@ -7,4 +7,5 @@ main = doctest
[ "-isrc"
, "src/FirstApp/Conf.hs"
, "src/FirstApp/DB.hs"
, "src/FirstApp/Types.hs"
]

View File

@ -53,24 +53,33 @@ data Comment = Comment
-- DeriveGeneric pragma to be added to the top of the file
deriving ( Show, Generic )
-- | modFieldLabel
-- >>> modFieldLabel "commentId"
-- "id"
-- >>> modFieldLabel "topic"
-- "topic"
-- >>> modFieldLabel ""
-- ""
modFieldLabel
:: String
-> String
modFieldLabel l =
A.camelTo2 '_'
. fromMaybe l
$ stripPrefix "comment" l
instance ToJSON Comment where
toEncoding = A.genericToEncoding opts
where
-- These options let us make some minor adjustments to how Aeson treats
-- our type. Our only adjustment is to alter the field names a little, to
-- remove the 'comment' prefix and camel case what is left of the name.
-- This accepts any 'String -> String' function but it's good to keep the
-- modifications simple.
-- remove the 'comment' prefix and use an Aeson function to handle the
-- rest of the name. This accepts any 'String -> String' function but it's
-- wise to keep the modifications simple.
opts = A.defaultOptions
{ A.fieldLabelModifier = modFieldLabel
}
-- Strip the prefix (which may fail if the prefix isn't present), fall
-- back to the original label if need be, then camel-case the name.
modFieldLabel l =
A.camelTo2 '_' . fromMaybe l
$ stripPrefix "comment" l
-- For safety we take our stored DbComment and try to construct a Comment that
-- we would be okay with showing someone. However unlikely it may be, this is a
-- nice method for separating out the back and front end of a web app and

View File

@ -7,4 +7,5 @@ main = doctest
[ "-isrc"
, "src/FirstApp/Conf.hs"
, "src/FirstApp/DB.hs"
, "src/FirstApp/Types.hs"
]