-
Notifications
You must be signed in to change notification settings - Fork 451
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
FreeC implementation #1048
FreeC implementation #1048
Conversation
8f3a497
to
a991fe9
Compare
Codecov Report
@@ Coverage Diff @@
## master #1048 +/- ##
============================================
- Coverage 42.39% 42.28% -0.12%
- Complexity 750 755 +5
============================================
Files 360 365 +5
Lines 9989 10219 +230
Branches 1082 1147 +65
============================================
+ Hits 4235 4321 +86
- Misses 5439 5562 +123
- Partials 315 336 +21
Continue to review full report at Codecov.
|
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.
Great start!
@@ -191,7 +191,7 @@ fun <T> Option<T>.getOrElse(default: () -> T): T = fold({ default() }, ::identit | |||
* | |||
* @param alternative the default option if this is empty. | |||
*/ | |||
inline fun <A, B : A> OptionOf<B>.orElse(alternative: () -> Option<B>): Option<B> = if (fix().isEmpty()) alternative() else fix() | |||
inline fun <A> OptionOf<A>.orElse(alternative: () -> Option<A>): Option<A> = if (fix().isEmpty()) alternative() else fix() |
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.
nice one
} | ||
|
||
internal object EitherToTry : FunctionK<EitherPartialOf<Throwable>, ForTry> { | ||
override fun <A> invoke(fa: Kind<EitherPartialOf<Throwable>, A>): Kind<ForTry, A> = |
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.
We have Try#toEither
. Perhaps this implementation can be exposed in the core as Either<Throwable, A>.toTry()
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.
Yeah sure. Btw should we add FunctionK
instances like this one to Arrow
? Or is there a ticket for this that I missed?
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.
@nomisRev they won't hurt, but it isn't a priority. Only the ones between Try/Either/Option and maybe ListK may be more interesting for now.
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.
@pakoito I could quickly add them in this PR.
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.
Just a friendly reminder that in 0.8.0 the use of ListK
and wrappers of one type arguments are rarely seen in user code unless they have polymorphic functions that expect values in the kind hierarchy.
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.
Awesome stuff! 👏
@@ -0,0 +1,14 @@ | |||
dependencies { |
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.
🎉 it's alive!
import arrow.typeclasses.MonadError | ||
|
||
/** | ||
* Free Monad with Catch (and Interruption). |
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.
We should mention and include fs2 here https://github.com/arrow-kt/arrow/blob/master/LICENSE#L20
} | ||
) | ||
|
||
/** @higherkind doesn't respect access modifier **/ |
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.
once it is migrated to the meta processor you may be able to get that info
this.fix().map(f) | ||
} | ||
|
||
internal fun <F> FreeC.Companion.applicative(): Applicative<FreeCPartialOf<F>> = object : FreeCApplicative<F> { } |
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.
Are these handwritten because they are internal? After 0.8.0 we should be able to encode internal instances in the ExtensionProcessor
so all the syntax they export it's also internal.
EQ_EITHER = Eq { a, b -> a.run(Try.monadError()) == b.run(Try.monadError()) } | ||
)) | ||
|
||
testLaws(MonadDeferLaws.laws( |
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 thought the laws where encoded such as if you just test the MonadDeferLaws
it will include all others in its hierarchy.
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, they're. This is left over from when I was debugging combinators in smaller sets at a time :D
} | ||
} | ||
|
||
"Running an suspended value"{ |
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.
s/an/a
} | ||
|
||
internal object EitherToTry : FunctionK<EitherPartialOf<Throwable>, ForTry> { | ||
override fun <A> invoke(fa: Kind<EitherPartialOf<Throwable>, A>): Kind<ForTry, A> = |
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.
Just a friendly reminder that in 0.8.0 the use of ListK
and wrappers of one type arguments are rarely seen in user code unless they have polymorphic functions that expect values in the kind hierarchy.
@nomisRev This is ready to go once you rebase from master |
… in matches over GADTs
41506b2
to
1358942
Compare
@raulraja could you review again? Also API / encoding of |
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 is excellent Simon! Kudos!, Our Free impl is now one step closer to have more superpowers than the scala cats one which had limited us In Freestyle big time
} | ||
is Fail<*, R> -> free | ||
is Interrupted<*, R, *> -> free | ||
else -> throw AssertionError("Unreachable") |
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.
In the event that this is ever thrown we should indicate in the exception message that this is potentially caused by a bug and provide a link to report it in the arrow issue tracker.
This PR is the starting point of a FS2 port or FS2 inspired stream lib.
In discussion with @raulraja we had the idea to move this to
arrow-free
as a replacement for the currentFree
implementation since we can then provide instance up toMonadDefer
(and later alsoSync
).If we are to move
FreeC
toarrow-free
I'd like to improve theResult
andViewL
code. Does any1 know if we could do something withinline classes
to createsealed class
wrappers without runtime overhead? I am assuming since they're going to be nested that they'll auto-box?