mirror of
https://github.com/qfpl/applied-fp-course.git
synced 2024-11-23 03:44:45 +03:00
Restructure part of the Conf.hs to provide more to do and with added guidance
This commit is contained in:
parent
dc42b2091f
commit
934f63497d
@ -11,9 +11,8 @@ inputs sufficiently.
|
||||
To build this application we're going to need some requirements:
|
||||
|
||||
### Requirements
|
||||
We have a WebThing(TM) somewhere and we would like, for some
|
||||
unknown reason, to be able to add comments to various topics on this
|
||||
WebThing(TM).
|
||||
We have a WebThing(TM) somewhere and we would like, for some unknown reason, to
|
||||
be able to add comments to various topics on this WebThing(TM).
|
||||
|
||||
### "Spec"
|
||||
Let's pretend we've completed a dozen specification meetings with our Project
|
||||
|
@ -110,12 +110,38 @@ parseOptions =
|
||||
-- need. The package we're using is the ``aeson`` package to parse some JSON and
|
||||
-- we'll pick the bits off the Object.
|
||||
|
||||
-- The documentation for this package will guide you in the right direction
|
||||
-- Complete the helper function that will be used to retrieve values off the
|
||||
-- JSON object.
|
||||
|
||||
-- | fromJsonObjWithKey
|
||||
-- >>> fromJsonObjWithKey "foo" id (encode "{\"foo\":\"Susan\"}")
|
||||
-- Last (Just "Susan")
|
||||
-- >>> fromJsonObjWithKey "foo" id (encode "{\"bar\":33}")
|
||||
-- Last Nothing
|
||||
fromJsonObjWithKey
|
||||
:: FromJSON a
|
||||
=> Text
|
||||
-> (a -> b)
|
||||
-> Aeson.Object
|
||||
-> Last b
|
||||
fromJsonObjWithKey =
|
||||
error "fromJsonObjWithKey not implemented"
|
||||
|
||||
-- Construct the function that will take a FilePath, read it in and attempt to
|
||||
-- decode it as a valid JSON object, using the ``aeson`` package. Then pull
|
||||
-- specific keys off this object and construct our ``PartialConf``. Using the
|
||||
-- function we wrote above to assist in pulling items off the object.
|
||||
parseJSONConfigFile
|
||||
:: FilePath
|
||||
-> IO PartialConf
|
||||
parseJSONConfigFile =
|
||||
error "parseJSONConfigFile not implemented"
|
||||
where
|
||||
-- Use the ``bracketOnError`` function to guard against exceptions.
|
||||
readObject
|
||||
:: IO (Maybe Aeson.Object)
|
||||
readObject =
|
||||
error "readObject not implemented"
|
||||
|
||||
-- | Command Line Parsing
|
||||
|
||||
|
@ -108,6 +108,20 @@ parseOptions fp = do
|
||||
|
||||
-- | File Parsing
|
||||
|
||||
-- | fromJsonObjWithKey
|
||||
-- >>> fromJsonObjWithKey "foo" id (encode "{\"foo\":\"Susan\"}")
|
||||
-- Last (Just "Susan")
|
||||
-- >>> fromJsonObjWithKey "foo" id (encode "{\"bar\":33}")
|
||||
-- Last Nothing
|
||||
fromJsonObjWithKey
|
||||
:: FromJSON a
|
||||
=> Text
|
||||
-> (a -> b)
|
||||
-> Aeson.Object
|
||||
-> Last b
|
||||
fromJsonObjWithKey k c obj =
|
||||
Last $ c <$> Aeson.parseMaybe (Aeson..: k) obj
|
||||
|
||||
-- Additional Exercise: Rewrite this without using Do notation
|
||||
-- 'fmap' should be sufficient.
|
||||
parseJSONConfigFile
|
||||
@ -118,25 +132,10 @@ parseJSONConfigFile fp = do
|
||||
pure . fromMaybe mempty $ toPartialConf <$> fc
|
||||
where
|
||||
toPartialConf cObj = PartialConf
|
||||
( offObj "port" Port cObj )
|
||||
( offObj "helloMsg" helloFromStr cObj )
|
||||
( fromJsonObjWithKey "port" Port cObj )
|
||||
( fromJsonObjWithKey "helloMsg" helloFromStr cObj )
|
||||
|
||||
-- Parse out the keys from the object, maybe...
|
||||
offObj
|
||||
:: FromJSON a
|
||||
=> Text
|
||||
-> (a -> b)
|
||||
-> Aeson.Object
|
||||
-> Last b
|
||||
offObj k c obj =
|
||||
-- Too weird ?
|
||||
Last $ c <$> Aeson.parseMaybe (Aeson..: k) obj
|
||||
|
||||
-- Use bracket to save ourselves from horrible exceptions, which are
|
||||
-- horrible.
|
||||
--
|
||||
-- Better ways to do this ?
|
||||
readObject
|
||||
readObject
|
||||
:: IO (Maybe Aeson.Object)
|
||||
readObject = bracketOnError
|
||||
(LBS.readFile fp)
|
||||
|
@ -116,6 +116,16 @@ parseOptions fp = do
|
||||
|
||||
-- | File Parsing
|
||||
|
||||
-- Parse out the keys from the object, maybe...
|
||||
fromJsonObjWithKey
|
||||
:: FromJSON a
|
||||
=> Text
|
||||
-> (a -> b)
|
||||
-> Aeson.Object
|
||||
-> Last b
|
||||
fromJsonObjWithKey k c obj =
|
||||
Last (c <$> Aeson.parseMaybe (Aeson..: k) obj)
|
||||
|
||||
parseJSONConfigFile
|
||||
:: FilePath
|
||||
-> IO PartialConf
|
||||
@ -124,23 +134,9 @@ parseJSONConfigFile fp = do
|
||||
pure . fromMaybe mempty $ toPartialConf <$> fc
|
||||
where
|
||||
toPartialConf cObj = PartialConf
|
||||
( fromObj "port" Port cObj )
|
||||
( fromObj "helloMsg" helloFromStr cObj )
|
||||
|
||||
-- Parse out the keys from the object, maybe...
|
||||
fromObj
|
||||
:: FromJSON a
|
||||
=> Text
|
||||
-> (a -> b)
|
||||
-> Aeson.Object
|
||||
-> Last b
|
||||
fromObj k c obj =
|
||||
Last (c <$> Aeson.parseMaybe (Aeson..: k) obj)
|
||||
|
||||
-- Use bracket to save ourselves from horrible exceptions, which are
|
||||
-- horrible.
|
||||
--
|
||||
-- Better ways to do this ?
|
||||
( fromJsonObjWithKey "port" Port cObj )
|
||||
( fromJsonObjWithKey "helloMsg" helloFromStr cObj )
|
||||
-- Use bracket to save ourselves from horrible exceptions.
|
||||
readObject
|
||||
:: IO (Maybe Aeson.Object)
|
||||
readObject = bracketOnError
|
||||
|
@ -129,6 +129,20 @@ parseOptions fp = do
|
||||
|
||||
-- | File Parsing
|
||||
|
||||
-- | fromJsonObjWithKey
|
||||
-- >>> fromJsonObjWithKey "foo" id (encode "{\"foo\":\"Susan\"}")
|
||||
-- Last (Just "Susan")
|
||||
-- >>> fromJsonObjWithKey "foo" id (encode "{\"bar\":33}")
|
||||
-- Last Nothing
|
||||
fromJsonObjWithKey
|
||||
:: FromJSON a
|
||||
=> Text
|
||||
-> (a -> b)
|
||||
-> Aeson.Object
|
||||
-> Last b
|
||||
fromJsonObjWithKey k c obj =
|
||||
Last $ c <$> Aeson.parseMaybe (Aeson..: k) obj
|
||||
|
||||
parseJSONConfigFile
|
||||
:: FilePath
|
||||
-> IO PartialConf
|
||||
@ -137,27 +151,12 @@ parseJSONConfigFile fp = do
|
||||
pure . fromMaybe mempty $ toPartialConf <$> fc
|
||||
where
|
||||
toPartialConf cObj = PartialConf
|
||||
( fromObj "port" Port cObj )
|
||||
( fromObj "helloMsg" helloFromStr cObj )
|
||||
( fromJsonObjWithKey "port" Port cObj )
|
||||
( fromJsonObjWithKey "helloMsg" helloFromStr cObj )
|
||||
-- Pull the extra keys off the configuration file.
|
||||
( fromObj "tableName" Table cObj )
|
||||
( fromObj "dbFilePath" id cObj )
|
||||
( fromJsonObjWithKey "tableName" Table cObj )
|
||||
( fromJsonObjWithKey "dbFilePath" id cObj )
|
||||
|
||||
-- Parse out the keys from the object, maybe...
|
||||
fromObj
|
||||
:: FromJSON a
|
||||
=> Text
|
||||
-> (a -> b)
|
||||
-> Aeson.Object
|
||||
-> Last b
|
||||
fromObj k c obj =
|
||||
-- Too weird ?
|
||||
Last $ c <$> Aeson.parseMaybe (Aeson..: k) obj
|
||||
|
||||
-- Use bracket to save ourselves from horrible exceptions, which are
|
||||
-- horrible.
|
||||
--
|
||||
-- Better ways to do this ?
|
||||
readObject
|
||||
:: IO (Maybe Aeson.Object)
|
||||
readObject = bracketOnError
|
||||
|
@ -129,9 +129,20 @@ parseOptions fp = do
|
||||
|
||||
-- | File Parsing
|
||||
|
||||
-- Avoiding too many complications with selecting a configuration file package
|
||||
-- from hackage. We'll use an encoding that you are probably familiar with, for
|
||||
-- better or worse, and write a small parser to pull out the bits we need.
|
||||
-- | fromJsonObjWithKey
|
||||
-- >>> fromJsonObjWithKey "foo" id (encode "{\"foo\":\"Susan\"}")
|
||||
-- Last (Just "Susan")
|
||||
-- >>> fromJsonObjWithKey "foo" id (encode "{\"bar\":33}")
|
||||
-- Last Nothing
|
||||
fromJsonObjWithKey
|
||||
:: FromJSON a
|
||||
=> Text
|
||||
-> (a -> b)
|
||||
-> Aeson.Object
|
||||
-> Last b
|
||||
fromJsonObjWithKey k c obj =
|
||||
Last (c <$> Aeson.parseMaybe (Aeson..: k) obj)
|
||||
|
||||
parseJSONConfigFile
|
||||
:: FilePath
|
||||
-> IO PartialConf
|
||||
@ -140,32 +151,12 @@ parseJSONConfigFile fp = do
|
||||
pure . fromMaybe mempty $ toPartialConf <$> fc
|
||||
where
|
||||
toPartialConf cObj = PartialConf
|
||||
( fromObj "port" Port cObj )
|
||||
( fromObj "helloMsg" helloFromStr cObj )
|
||||
( fromJsonObjWithKey "port" Port cObj )
|
||||
( fromJsonObjWithKey "helloMsg" helloFromStr cObj )
|
||||
-- Pull the extra keys off the configuration file.
|
||||
( fromObj "tableName" Table cObj )
|
||||
( fromObj "dbFilePath" id cObj )
|
||||
( fromJsonObjWithKey "tableName" Table cObj )
|
||||
( fromJsonObjWithKey "dbFilePath" id cObj )
|
||||
|
||||
-- Parse out the keys from the object, maybe...
|
||||
-- >>> fromObj "foo" id (encode "{\"foo\":\"Susan\"}")
|
||||
-- Last (Just "Susan")
|
||||
-- >>> fromObj "foo" id (encode "{\"bar\":33}")
|
||||
-- Last Nothing
|
||||
--
|
||||
fromObj
|
||||
:: FromJSON a
|
||||
=> Text
|
||||
-> (a -> b)
|
||||
-> Aeson.Object
|
||||
-> Last b
|
||||
fromObj k c obj =
|
||||
-- Too weird ?
|
||||
Last (c <$> Aeson.parseMaybe (Aeson..: k) obj)
|
||||
|
||||
-- Use bracket to save ourselves from horrible exceptions, which are
|
||||
-- horrible.
|
||||
--
|
||||
-- Better ways to do this ?
|
||||
readObject
|
||||
:: IO (Maybe Aeson.Object)
|
||||
readObject = bracketOnError
|
||||
|
Loading…
Reference in New Issue
Block a user