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

logic: make S.and and S.or monomorphic, and remove S.xor #279

Merged
merged 1 commit into from
Nov 13, 2016

Conversation

davidchambers
Copy link
Member

Commit message:

The first of the three functions to be added was S.or, to allow:

> S.or(S.Nothing, S.Just(42))
Just(42)

This is possible in Haskell too:

> Nothing <|> Just 42
Just 42

The <|> operator, though, does not accept Boolean operands, as the Bool type does not satisfy the requirements of the Alternative type class.

The Bool type has two monoids:

  • All
    • mempty = True
    • mappend = (&&)
  • Any
    • mempty = False
    • mappend = (||)

Overloading S.or for Boolean arguments requires implicitly selecting All as the Boolean monoid. This necessitates the definition and use of a Sanctuary-specific Monoid-like type class (the standard Monoid type class defined in sanctuary-type-classes rejects Boolean values because fantasy-land/empty is not defined for the Boolean type).

This commit updates the type of S.or to match that of Haskell's (||):

S.or :: Boolean -> Boolean -> Boolean

The <|> behaviour currently provided by S.or is undoubtedly useful, but will be provided by S.alt once Sanctuary wrappers are added for the functions defined in sanctuary-type-classes:

S.alt :: Alt f => f a -> f a -> f a

S.and is currently polymorphic for consistency with S.or rather than to address any particular need. This commit updates the type of S.and to match that of Haskell's (&&):

S.and :: Boolean -> Boolean -> Boolean

Boolean XOR does not warrant inclusion, so this commit removes S.xor.

This commit also removes the toBoolean methods which existed solely to allow S.and, S.or, and S.xor to operate on Maybe and Either values.

I've been grappling with this for months. Now that alt exists we can simplify these functions which have been causing me so much trouble. :)

For context, S.or was added all the way back in #1, and S.and and S.xor were added in #26.

The first of the three functions to be added was S.or, to allow:

    > S.or(S.Nothing, S.Just(42))
    Just(42)

This is possible in Haskell too:

    > Nothing <|> Just 42
    Just 42

The <|> operator, though, does not accept Boolean operands, as the Bool
type does not satisfy the requirements of the Alternative type class.

The Bool type has two monoids:

  - All
    - mempty = True
    - mappend = (&&)
  - Any
    - mempty = False
    - mappend = (||)

Overloading S.or for Boolean arguments requires implicitly selecting
All as the Boolean monoid. This necessitates the definition and use of
a Sanctuary-specific Monoid-like type class (the standard Monoid type
class defined in sanctuary-type-classes rejects Boolean values because
fantasy-land/empty is not defined for the Boolean type).

This commit updates the type of S.or to match that of Haskell's (||):

    S.or :: Boolean -> Boolean -> Boolean

The <|> behaviour currently provided by S.or is undoubtedly useful,
but will be provided by S.alt once Sanctuary wrappers are added for
the functions defined in sanctuary-type-classes:

    S.alt :: Alt f => f a -> f a -> f a

S.and is currently polymorphic for consistency with S.or rather than
to address any particular need. This commit updates the type of S.and
to match that of Haskell's (&&):

    S.and :: Boolean -> Boolean -> Boolean

Boolean XOR does not warrant inclusion, so this commit removes S.xor.

This commit also removes the "toBoolean" methods which existed solely
to allow S.and, S.or, and S.xor to operate on Maybe and Either values.
@ScottFreeCode
Copy link

For anyone who stumbles on this and wonders: if I wanted to get a first-class function boolean exclusive-or, what would be the recommended way to do so with S.xor removed rather than booleanized?

@davidchambers
Copy link
Member Author

@ScottFreeCode, thanks to #289 you'll be able to use curry2 to define xor yourself:

//    xor :: Boolean -> Boolean -> Boolean
const xor = S.curry2((x, y) => x !== y);

Rather than write xor(x, y) it would arguably be clearer to write x !== y. If you want to take advantage of partial application, though, xor would be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants