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

Add Function1 #137

Merged
merged 13 commits into from
Jul 21, 2017
Merged

Add Function1 #137

merged 13 commits into from
Jul 21, 2017

Conversation

pakoito
Copy link
Member

@pakoito pakoito commented Jul 21, 2017

Another breakthrough in language limitations. This PR adds the first kind projection using skolemization!

The PR adds a HK wrapper for Functions with 1 parameter, along with an instance of monad() and monadReader()

For a background on the buzzwords, check these links:

https://github.com/non/kind-projector
https://gist.github.com/jdegoes/97459c0045f373f4eaf126998d8f65dc#skolemization

@pakoito pakoito self-assigned this Jul 21, 2017
@raulraja raulraja mentioned this pull request Jul 21, 2017
54 tasks
@codecov-io
Copy link

codecov-io commented Jul 21, 2017

Codecov Report

Merging #137 into master will increase coverage by 0.1%.
The diff coverage is 59.09%.

Impacted file tree graph

@@             Coverage Diff             @@
##             master     #137     +/-   ##
===========================================
+ Coverage     51.98%   52.09%   +0.1%     
- Complexity      160      163      +3     
===========================================
  Files            66       68      +2     
  Lines          1458     1478     +20     
  Branches        175      175             
===========================================
+ Hits            758      770     +12     
- Misses          629      637      +8     
  Partials         71       71
Impacted Files Coverage Δ Complexity Δ
...src/main/kotlin/kategory/instances/TryInstances.kt 55.55% <ø> (ø) 0 <0> (ø) ⬇️
...tegory/src/main/kotlin/kategory/arrow/Function0.kt 58.82% <100%> (ø) 1 <0> (ø) ⬇️
kategory/src/main/kotlin/kategory/data/Composed.kt 80% <100%> (ø) 0 <0> (ø) ⬇️
...in/kotlin/kategory/instances/Function1Instances.kt 44.44% <44.44%> (ø) 0 <0> (?)
...tegory/src/main/kotlin/kategory/arrow/Function1.kt 63.63% <63.63%> (ø) 3 <3> (?)
kategory/src/main/kotlin/kategory/data/Reader.kt 87.5% <0%> (+12.5%) 3% <0%> (ø) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bd5f070...48a0307. Read the comment docs.

operator fun <P> invoke(p: P): R
}

interface FunctionSurject<in P> {
Copy link
Member

Choose a reason for hiding this comment

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

where is needed this interface?

Copy link
Member Author

Choose a reason for hiding this comment

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

Nowhere at the moment. It will, as it's dual of the Inject.

Copy link
Member

Choose a reason for hiding this comment

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

ok, make sense

override fun <A> pure(a: A): Function1<P, A> =
{ _: P -> a }.k()

override fun <A, B> map(fa: HK<Function1.F, A>, f: (A) -> B): HK<Function1.F, B> =
Copy link
Member

Choose a reason for hiding this comment

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

return type could be Function1<F,B> ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Same as above, the parameter info isn't available to the compiler. It infers Function1<B, B>.

Monad<Function1.F>,
MonadReader<Function1.F, P> {

override fun ask(): HK<Function1.F, P> =
Copy link
Member

Choose a reason for hiding this comment

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

what the reason to not return Function1<F,P>? not expose to callers FunctionInject?

Copy link
Member Author

Choose a reason for hiding this comment

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

The compiler doesn't have enough information about the generic F in this context, so it fails.

@@ -0,0 +1,9 @@
package kategory

interface FunctionInject<out R> {
Copy link
Member

Choose a reason for hiding this comment

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

we want those Bijections to be public?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, we have very few private things on the repo. It's all tools, really.

fun <R> Function1F<R>.ev(): FunctionInject<R> =
this as FunctionInject<R>

// We don't we want an inherited class to avoid equivalence issues, so a simple HK wrapper will do
Copy link
Member

Choose a reason for hiding this comment

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

We don't we want

@RunWith(KTestJUnitRunner::class)
class Function1Test : UnitSpec() {
init {
testLaws(MonadLaws.laws(Function1.monad<Int>(), object : Eq<HK<Function1.F, Int>> {
Copy link
Member

Choose a reason for hiding this comment

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

Since this a new instance of MonadReader and so far we have Kleisli and this one I think it's time to add the missing MonadReader laws and apply them both here and in Kleisli, fine if addressed in a separate PR.

Copy link
Member

Choose a reason for hiding this comment

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

Also just realized we are missing Category and MonoidK as typeclasses, also addressable in a separate PR. Function1 should also have an instance for MonoidK

a.ev()(1) == b.ev()(1)
}))

"Function1Monad.binding should for comprehend over all values of multiple Function0" {
Copy link
Member

Choose a reason for hiding this comment

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

We may be able to add generic tests for Monad and Applicative to tests comprehensions and the applicative builder works for all monads and applicative instances instead of hardcoding these on each datatype test.

Copy link
Member

@ffgiraldez ffgiraldez left a comment

Choose a reason for hiding this comment

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

Good job, I wanna have more brainwave like you have to implement this.

@ffgiraldez ffgiraldez merged commit f3ede04 into master Jul 21, 2017
@ffgiraldez ffgiraldez deleted the paco-function1 branch July 21, 2017 10:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants