-
-
Notifications
You must be signed in to change notification settings - Fork 39
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
Conversation
There was a problem hiding this 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.
There was a problem hiding this 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 ⏩
src/Toml/Codec/Combinator/Custom.hs
Outdated
@@ -10,6 +10,7 @@ See examples below of the situations you may need the following combinators. | |||
|
|||
@since 1.3.0.0 | |||
-} | |||
{-# LANGUAGE LambdaCase #-} |
There was a problem hiding this comment.
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 🙂
{-# LANGUAGE LambdaCase #-} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
src/Toml/Codec/Combinator/Custom.hs
Outdated
@@ -20,16 +21,21 @@ module Toml.Codec.Combinator.Custom | |||
-- * Validation | |||
, validate | |||
, validateIf | |||
|
|||
-- * Transform |
There was a problem hiding this comment.
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 🙂
-- * Transform | |
-- * With the errors reporting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!
src/Toml/Codec/Combinator/Custom.hs
Outdated
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' |
There was a problem hiding this comment.
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:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're totally right! 😉
src/Toml/Codec/Combinator/Custom.hs
Outdated
either (Codec r w) = Codec r' $ \case | ||
Left x' -> pure . Left $ x' | ||
Right x' -> fmap Right . w $ x' | ||
where r' = pure . validationToEither . r |
There was a problem hiding this comment.
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 🙂
where r' = pure . validationToEither . r | |
where | |
newCodecRead :: TomlEnv (Either [TomlDecodeError] a) | |
newCodecRead = Success . validationToEither . oldCodecRead |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
)
There was a problem hiding this comment.
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 🤔
There was a problem hiding this comment.
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
.
There was a problem hiding this 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
src/Toml/Codec/Combinator/Custom.hs
Outdated
@@ -10,6 +10,7 @@ See examples below of the situations you may need the following combinators. | |||
|
|||
@since 1.3.0.0 | |||
-} | |||
{-# LANGUAGE LambdaCase #-} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
src/Toml/Codec/Combinator/Custom.hs
Outdated
@@ -20,16 +21,21 @@ module Toml.Codec.Combinator.Custom | |||
-- * Validation | |||
, validate | |||
, validateIf | |||
|
|||
-- * Transform |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure!
src/Toml/Codec/Combinator/Custom.hs
Outdated
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' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're totally right! 😉
src/Toml/Codec/Combinator/Custom.hs
Outdated
either (Codec r w) = Codec r' $ \case | ||
Left x' -> pure . Left $ x' | ||
Right x' -> fmap Right . w $ x' | ||
where r' = pure . validationToEither . r |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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 🤔
genTValue = Gen.element [ TBool | ||
, TInteger | ||
, TDouble | ||
, TText | ||
, TZoned | ||
, TLocal | ||
, TDay | ||
, THours | ||
, TArray | ||
] |
There was a problem hiding this comment.
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
🙂
Closing due to the inactivity. |
Implement the
either
combinator from #326