Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'either' combinator for TomlCodec #346

Closed
wants to merge 3 commits into from

Conversation

markus1189
Copy link

@markus1189 markus1189 commented Oct 17, 2020

Implement the either combinator from #326

Copy link
Contributor

@hint-man hint-man bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no place for me here... I will choose the truth I like.

@markus1189 markus1189 marked this pull request as ready for review October 17, 2020 08:49
Copy link
Contributor

@chshersh chshersh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markus1189 Thanks for your contribution! Much appreciated 🙂
I left some comments on possible code improvements and some suggestions on how to move this forward ⏩

@@ -10,6 +10,7 @@ See examples below of the situations you may need the following combinators.

@since 1.3.0.0
-}
{-# LANGUAGE LambdaCase #-}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This extension is enabled in the tomland.cabal file by default in all modules, so no need to add it here 🙂

Suggested change
{-# LANGUAGE LambdaCase #-}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

@@ -20,16 +21,21 @@ module Toml.Codec.Combinator.Custom
-- * Validation
, validate
, validateIf

-- * Transform
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename the section to give some more meaning to it 🙂

Suggested change
-- * Transform
-- * With the errors reporting

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure!

either :: TomlCodec a -> TomlCodec (Either [TomlDecodeError] a)
either (Codec r w) = Codec r' $ \case
Left x' -> pure . Left $ x'
Right x' -> fmap Right . w $ x'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case looks like the Traversable instance for Either, so you can use a single function traverse instead of a manual case:

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're totally right! 😉

either (Codec r w) = Codec r' $ \case
Left x' -> pure . Left $ x'
Right x' -> fmap Right . w $ x'
where r' = pure . validationToEither . r
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename variables for clarity, and also use Success here for clarity. Just to make the code more maintainable 🙂

Suggested change
where r' = pure . validationToEither . r
where
newCodecRead :: TomlEnv (Either [TomlDecodeError] a)
newCodecRead = Success . validationToEither . oldCodecRead

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I agree, I moved out both newCodecRead and newCodecWrite

@@ -25,3 +26,6 @@ customSpec = describe "Combinator.Custom: Roundtrip tests" $ do
codecRoundtrip "TextBy "
(Toml.textBy (Text.pack . show) (first Text.pack . readEither . Text.unpack))
Gen.genInt
codecRoundtrip "either "
(Toml.either . Toml.bool)
(Right <$> Gen.genBool)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you are testing the either combinator only on values generated with the constructor Right, but we actually want to test on both Left and Right. So, we need to generate either a list of decode errors or a different value (in your case it's Bool)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm I'm no longer sure if TomlCodec (Either [TomlDecodeError] a) is correct 🤔

We probably don't want to enode a Left [TomlDecodeError]... Maybe we should change either to:

either :: Codec i o -> Codec i (Either [TomlDecodeError] o)

and then we need to use something other than codecRoundtrip in the test 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markus1189 I think it is okay to have TomlCodec in type as TomlDecodeError works with TomlCodec 🙂
You can just change the generator to something with Gen.either.

src/Toml/Codec/Combinator/Custom.hs Outdated Show resolved Hide resolved
@chshersh chshersh added codec Conversion between TOML and custom user data types hacktoberfest-accepted Accept contributions during Hacktoberfest labels Oct 17, 2020
Copy link
Author

@markus1189 markus1189 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @chshersh for the friendly review! I left some comments in answer

@@ -10,6 +10,7 @@ See examples below of the situations you may need the following combinators.

@since 1.3.0.0
-}
{-# LANGUAGE LambdaCase #-}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

@@ -20,16 +21,21 @@ module Toml.Codec.Combinator.Custom
-- * Validation
, validate
, validateIf

-- * Transform
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure!

either :: TomlCodec a -> TomlCodec (Either [TomlDecodeError] a)
either (Codec r w) = Codec r' $ \case
Left x' -> pure . Left $ x'
Right x' -> fmap Right . w $ x'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're totally right! 😉

either (Codec r w) = Codec r' $ \case
Left x' -> pure . Left $ x'
Right x' -> fmap Right . w $ x'
where r' = pure . validationToEither . r
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I agree, I moved out both newCodecRead and newCodecWrite

@@ -25,3 +26,6 @@ customSpec = describe "Combinator.Custom: Roundtrip tests" $ do
codecRoundtrip "TextBy "
(Toml.textBy (Text.pack . show) (first Text.pack . readEither . Text.unpack))
Gen.genInt
codecRoundtrip "either "
(Toml.either . Toml.bool)
(Right <$> Gen.genBool)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm I'm no longer sure if TomlCodec (Either [TomlDecodeError] a) is correct 🤔

We probably don't want to enode a Left [TomlDecodeError]... Maybe we should change either to:

either :: Codec i o -> Codec i (Either [TomlDecodeError] o)

and then we need to use something other than codecRoundtrip in the test 🤔

Comment on lines +194 to +203
genTValue = Gen.element [ TBool
, TInteger
, TDouble
, TText
, TZoned
, TLocal
, TDay
, THours
, TArray
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can use enumBounded here, if we derive Enum for TValue 🙂

@vrom911 vrom911 changed the base branch from master to main November 6, 2020 16:43
@vrom911
Copy link
Member

vrom911 commented Feb 8, 2021

Closing due to the inactivity.
Feel free to reopen if you would like to continue working on it 🙂

@vrom911 vrom911 closed this Feb 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
codec Conversion between TOML and custom user data types hacktoberfest-accepted Accept contributions during Hacktoberfest
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants