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

Monadic composition #56

Closed
wants to merge 3 commits into from
Closed

Monadic composition #56

wants to merge 3 commits into from

Conversation

sharplet
Copy link
Contributor

@sharplet sharplet commented Dec 2, 2015

Monadic composition

Here's how I'm using this with Result and RAC:

request(.GET, "/myendpoint")
  .flatMap(.Concat, transform: SignalProducer.init  (parseJSON >-> decodeSomething))

Basically, this really helps to avoid explicit closures everywhere, which I value for both readability and the avoidance of capturing strong references to self.


The composition operator

In the example above I'm using as the composition operator (which can be typed on US keyboards with Opt-8). I threw this into the specs for this PR, because I think it really helps their clarity.

I'd love your feedback on:

  • Whether you agree about the improvement to the specs
  • What you think about adding this to the public API of Runes in a subsequent commit

}

// (f <=< g) <=< h = f <=< (g <=< h)
property("right-to-left Kleisli composition of monads") <- forAll { (x: Int, fa: ArrowOf<Int, Int>, fb: ArrowOf<Int, Int>, fc: ArrowOf<Int, Int>) in

Choose a reason for hiding this comment

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

Line Length Violation: Line should be 100 characters or less: currently 156 characters (line_length)
Variable Name Min Length Rule Violation: Variable name should be 2 characters or more: currently 1 characters (variable_name_min_length)
Variable Name Min Length Rule Violation: Variable name should be 3 characters or more: currently 2 characters (variable_name_min_length)

@gfontenot
Copy link
Collaborator

Ignore these hound warnings for now. I'm not sure it's worth keeping on for this repo.

I'll check this out tomorrow morning.

On Dec 1, 2015, at 21:39, Adam Sharp notifications@github.com wrote:

Monadic composition

Here's how I'm using this with Result and RAC:

request(.GET, "/myendpoint")
.flatMap(.Concat, transform: SignalProducer.init • (parseJSON >-> decodeSomething))
Basically, this really helps to avoid explicit closures everywhere, which I value for both readability and the avoidance of capturing strong references to self.

The composition operator

In the example above I'm using • as the composition operator (which can be typed on US keyboards with Opt-8). I threw this into the specs for this PR, because I think it really helps their clarity.

I'd love your feedback on:

Whether you agree about the improvement to the specs
What you think about adding this to the public API of Runes in a subsequent commit
You can view, comment on, or merge this pull request online at:

#56

Commit Summary

Clarify specs by defining • as the composition operator
Explicitly specify indentation settings in project
Add >-> and <-< monadic composition operators
File Changes

M Runes.xcodeproj/project.pbxproj (14)
M Source/Array.swift (28)
M Source/Optional.swift (30)
M Source/Runes.swift (24)
M Tests/Helpers/Functions.swift (4)
A Tests/Helpers/Operators.swift (8)
M Tests/Tests/ArraySpec.swift (36)
M Tests/Tests/OptionalSpec.swift (36)
Patch Links:

https://github.com/thoughtbot/Runes/pull/56.patch
https://github.com/thoughtbot/Runes/pull/56.diff

Reply to this email directly or view it on GitHub.

}

/**
like `>->`, but with the arguments flipped
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe add the explicit documentation here as well, and move this note down. I'd be kinda annoyed to have to look up documentation for a different operator to see what this one does.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah you're totally right. Done in c76a3e9.

@tonyd256
Copy link

tonyd256 commented Dec 2, 2015

I all for this! Should there be an operators file for composition? do we want to include that in the Runes file so everyone has access even if it's not a monadic operator?

@gfontenot
Copy link
Collaborator

This is dope as hell. Love it.

It does have me wishing we could break this up into submodules somehow though. It'd feel great to be able to import Runes.Monad or import Runes.Applicative instead of it being all or none. AFAIK, that's not possible though (this is me hoping someone "actually"s me and shows me how to do that).

I also think that for now, we should avoid introducing • as an operator here. Right now, Runes is really about monadic operations, and function composition (like function application) is just outside that scope. It's reasonable to think that maybe that should change, but I feel like that's a different discussion.

Only other note: can you (should you?) remove the free compose function from the test suite entirely? I'd rather not have the duplicate implementation in there.

}

/**
compose two functions that produce results in a context, from right to left, returning a result in that context

Choose a reason for hiding this comment

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

Line Length Violation: Line should be 100 characters or less: currently 111 characters (line_length)

Choose a reason for hiding this comment

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

Line Length Violation: Line should be 100 characters or less: currently 111 characters (line_length)

@sharplet
Copy link
Contributor Author

sharplet commented Dec 2, 2015

It does have me wishing we could break this up into submodules somehow though.

Yeah I've wished for the same thing. I played around with trying to get umbrella frameworks to work, and embedding the subframeworks inside, but I couldn't work out how to write a valid module map for it, and I have no idea if that even can work.

I also think that for now, we should avoid introducing • as an operator here. Right now, Runes is really about monadic operations, and function composition (like function application) is just outside that scope. It's reasonable to think that maybe that should change, but I feel like that's a different discussion.

Yep, I agree. 👍

This is kinda starting to get into overlap territory with something like https://github.com/robrix/Prelude, which defines >>> and <<< as the composition operators.

Only other note: can you (should you?) remove the free compose function from the test suite entirely? I'd rather not have the duplicate implementation in there.

I didn't think there was any need for both (seeing as the free function wasn't being used anymore). Taken care of here.

@gfontenot
Copy link
Collaborator

Merged as 42fbd8f

Thanks!

@gfontenot gfontenot closed this Dec 15, 2015
@sharplet
Copy link
Contributor Author

@sharplet sharplet mentioned this pull request Jan 13, 2016
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.

4 participants