-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
WIP: add some missing applicative and monad ops #1216
Conversation
@@ -38,6 +38,14 @@ import simulacrum.typeclass | |||
def replicateA[A](n: Int, fa: F[A]): F[List[A]] = | |||
sequence(List.fill(n)(fa)) | |||
|
|||
/** Returns the given argument if `cond` is `false`, otherwise, unit lifted into F. */ | |||
def unlessA[A](cond: Boolean)(f: => F[A]): F[Unit] = |
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.
what's the story on call-by-name vs Eval[F[A]]
. Seems like the later is more the cats style (maybe have both, strict and Eval)?
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.
Ok I'll change those to strict + Eval
. Honestly I have never had a case where it mattered, but scalaz does it this way so it's probably worthwhile to have the nonstrict version.
I think the All the syntax methods on the same type (like most of them seemed to be on |
@peterneyens ok, if it's just based on shape that simplifies things. I'll do that. |
@tpolecat as a follow-up to @peterneyens's comment, for the common cases, Simulacrum will generate the |
It looks like many of these really want |
Current coverage is 88.59%@@ master #1216 diff @@
==========================================
Files 234 235 +1
Lines 3144 3165 +21
Methods 3085 3110 +25
Messages 0 0
Branches 57 52 -5
==========================================
Hits 2804 2804
- Misses 340 361 +21
Partials 0 0
|
@johnynek possibly re: Thanks all for your comments, I'll rework a few things tonight. 🐔 |
Re: All of my reservations however lie in the assumption that there are data types with |
@adelbertc I've wondered the same about instances with In #1117 (which by the way it would be great if we could get another reviewer or two on there), the existing |
So do I need 4 versions of every method, with/without |
I would just not have MonadRec On Jul 19, 2016 12:50, "Rob Norris" notifications@github.com wrote:
|
Seems like the methods ( |
So, I would actually argue that any time we do a recursive flatMap we should ONLY use Then, we could have something like: def toRecursiveUnsafe[M[_]](m: Monad[M]): MonadRec[M] = // just implements tailRecM with a recursive flatMap otherwise proxy
def toRecursiveUnsafe[M[_]](m: FlatMap[M]): FlatMapRec[M] = // just implements tailRecM with a recursive flatMap, otherwise proxy. I think it is simpler to have this rule than to maybe blow the stack unless we have the right thing. Let the caller explicitly opt in to the risk. In fact, many If we don't think this is needed, why not put It may be a bit extreme, but to me this is the whole point of having |
here is a PR to remove FlatMapRec so we don't have this duplication of methods to get the nice IO methods you want. I think everything can just implement tailRecM: #1280 |
I'll come back to this at some point. No time now. |
This pulls in some combinators from scalaz that never made it into cats. These are very useful when working with
IO
-like data types. I need some help with style and conventions before I put more time into this:Also:
👎 pending (at least) items above.