Skip to content

[#172] Add Semigroup and Monoid instances to Validation#175

Merged
vrom911 merged 4 commits intokowainik:masterfrom
mauriciofierrom:master
Aug 6, 2019
Merged

[#172] Add Semigroup and Monoid instances to Validation#175
vrom911 merged 4 commits intokowainik:masterfrom
mauriciofierrom:master

Conversation

@mauriciofierrom
Copy link
Copy Markdown
Contributor

Resolves #172.

  • Removes liftA2 custom definition.
  • Adds Semigroup and Monoid instances to Validation type.
  • Improves documentation for Validation module with use cases.

Checklist:

HLint

  • I've changed the exposed interface (add new reexports, remove reexports, rename reexported things, etc.).
    • I've updated hlint.dhall accordingly to my changes (add new rules for the new imports, remove old ones, when they are outdated, etc.).
    • I've generated the new .hlint.yaml file (see this instructions).

General

  • I've updated the CHANGELOG with the short description of my latest changes.
  • All new and existing tests pass.
  • I keep the code style used in the files I've changed (see style-guide for more details).
  • I've used the stylish-haskell file.
  • My change requires the documentation updates.
    • I've updated the documentation accordingly.
  • I've added the [ci skip] text to the docs-only related commit's name.

@chshersh chshersh requested review from chshersh and vrom911 July 29, 2019 16:26
@chshersh chshersh added doc README, Haddock documentation, tutorials enhancement New feature or request extra Relude.Extra labels Jul 29, 2019
Copy link
Copy Markdown
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.

@mauriciofierrom Thanks for your work! This is a useful addition to the library 👍 You asked about documentation and how it can be improved. And here are my thoughts. Validation has many instances with non-obvious behaviour. It's not clear how the instances are implemented without looking at the code. And all these instances (Applicative, Semigroup, Monoid, Alternative) solve different problems. So I would like to have more expanded top-level Haddock for this module that describes use cases and recommends instances. Something like that:

  1. If you want to validate data and return combined errors or result of sequential functional applications, use Applicative instance. This instance returns Success only when all values are Success.
  2. If you want to return the combined result of all errors or the first successful result, use Alternative.
  3. If you're going to combine errors and validation results monoidally, use Semigroup/Monoid instance. Use First/Last/[] monoids to specify how you want to combine errors/results. This instance returns Success only when all values are Success.

Something like that. Just a short description of what instances and functions users need to use when they want specific behaviour. Does this make sense?

CHANGELOG.md Outdated
* [#155](https://github.com/kowainik/relude/issues/155):
Implement `Relude.Extra.Foldable` module.
* Re-export `GHC.Float.atan2`.
* Add `Monoid` and `Semigroup` instances for `Validation` type
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for updating CHANGELOG as well! Could you also write it in the format with the link to the corresponding issue number?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oops, sorry! I'll change this.

-}

instance (Semigroup e, Semigroup a) => Semigroup (Validation e a) where
x <> y = (<>) <$> x <*> y
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would love to have several changes in this implementation:

  1. Add explicit function signature in the spirit of all instances.
  2. Use liftA2. Basically, this function can be implemented simpler:
    (<>) = liftA2 (<>)
  3. Add {-# INLINE #-} pragmas to <> and mempty

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I'll change this as well.

Failure ["Not correct","Not correct either"]

>>> liftA2 (+) a b
>>> (+) <$> a <*> b
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The fact that we don't implement liftA2 doesn't mean that we cannot use it. I think that it's completely okay to use liftA2 in this documentation.

@mauriciofierrom
Copy link
Copy Markdown
Contributor Author

Yes, that make sense. I'll work on that. Thanks for your explanation!

Copy link
Copy Markdown
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.

Thanks for your effort! This looks great 🙂 I think documentation always can be improved but this is already very useful 👍

Copy link
Copy Markdown
Member

@vrom911 vrom911 left a comment

Choose a reason for hiding this comment

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

Looks great! 👍

@vrom911 vrom911 merged commit 3691cb0 into kowainik:master Aug 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc README, Haddock documentation, tutorials enhancement New feature or request extra Relude.Extra

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add useful Semigroup and Monoid instances for Validation

3 participants