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

new function existsAnd : (a -> Bool) -> Maybe a -> Bool #56

Open
skyqrose opened this issue May 23, 2020 · 3 comments
Open

new function existsAnd : (a -> Bool) -> Maybe a -> Bool #56

skyqrose opened this issue May 23, 2020 · 3 comments

Comments

@skyqrose
Copy link
Collaborator

Maybe is basically a List with 0 or 1 elements. All the functions in List and Haskell's Foldable class have equivalents in Maybe or Maybe.Extra, or don't make sense with only 1 element, except for fold (which is handled by #55) and any/all.

The difference between any and all for Maybe would be in the empty case.

any : (a -> Bool) -> Maybe a -> Bool
any predicate mx =
  case mx of
    Nothing -> False
    Just x -> predicate x

all : (a -> Bool) -> Maybe a -> Bool
all predicate mx =
  case mx of
    Nothing -> True
    Just x -> predicate x

I think this is a pretty simple thing to want to do that Maybe and Maybe.Extra don't support right now. There isn't really a good way to run a predicate on a Maybe. You could do filter predicate >> isJust or map predicate >> withDefault False, but those don't really express the idea of "do I have something that matches" well.

I found several examples of people implementing any with a variety of names:
exists
extractBool
existsAnd
(??)
maybePredicate
maybePredicate

I saw no examples of people implementing all.

I propose adding a single new function for any, but with a different name that's less list-like and more maybe-like. Maybe existsAnd or isJustAnd. I think those names would look good in a pipeline.

[1, 2, 3]
|> List.head
|> Maybe.Extra.existsAnd isEven

Thoughts?

@NeilW
Copy link

NeilW commented May 23, 2020

I've tried various streaming's versions of the functions to make

https://github.com/NeilW/elm-orderbook/blob/master/src/OrderBook.elm#L192

clearer, but nothing is as clear as writing it out. And even that's not that clear :-)

I actually want all here I think, Along with something to do Bool -> a -> Maybe a

which would perhaps allow a curry

buyMaybeFillable activeBuy =
Maybe.Extra.all ("<=" passiveSell.price) activeBuy.price
    |> Maybe.Extra.toMaybe

@skyqrose
Copy link
Collaborator Author

That Bool -> a -> Maybe a function was considered here: #49 It was ultimately rejected, because

It slightly encourages invalid states. For example, there's an implicit assumption that's not reflected in the types that guarded (not << List.isEmpty) will never return Just []. A safer way to model the types would be a Maybe Nonempty or just passing the List through and casing on the format later.

That would suggest using config.isFillable : ... -> Bool

buyIsFillable : OrderRequest -> ( Order, Heap Order ) -> Bool
buyIsFillable activeBuy ( passiveSell, _newSell ) =
    Maybe.Extra.all (\buyPrice -> buyPrice >= passiveSell.price) activeBuy.price

...

config.getpassiveQueue book
    |> Heap.pop
    |> Maybe.Extra.filter (config.isFillable activeRequest)

But I see the need for all here. And even if it only gets a little use, having an any/all pair could make both of them clearer and help people think about what the right thing to do with the nothing case is. So we'd just need a pair of names that makes their similarities and differences clear. Some ideas:

  • any/all (Not clear what they mean if you don't see the similarities to List)
  • testAndIsJust/testOrIsNothing
  • isJustAndPasses/isNothingOrPasses
  • predicateDefaultFalse/predicateDefaultTrue

@NeilW
Copy link

NeilW commented May 24, 2020

  • existsAnd / notExistsOr
  • isJustAnd / isNothingOr

With the last two fitting nicely with the existing isJust and isNothing function names

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

No branches or pull requests

2 participants