-
Notifications
You must be signed in to change notification settings - Fork 14
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
Adding implementation for the fn.monad.Option
#21
Comments
fn.monad.Optional
fn.monad.Option
Hi @grayfall, thanks for reporting the issue. That's what we are here for -- to keep If you would like to work on this, please feel free to fork and make a PR. If you are not comfortable adding the code, I can work on it or @low-ghost would probably enjoy working on it. He likes all things monad. :) For now I will add this to our v1.0 milestone, since it doesn't make sense to release a "version 1" with |
fn.monad.Option IS implemented. It is an abstract base class. See for yourself; here's an example from the docs, slightly modified to produce testable output from operator import methodcaller
from fn.monad import optionable
class Request(dict):
@optionable
def parameter(self, name):
return self.get(name, None)
def get_uppercased(r, name):
return (r.parameter(name)
.map(methodcaller("strip"))
.filter(len)
.map(methodcaller("upper"))
.get_or("-"))
r = Request(testing="Fixed", empty=" ")
print(get_uppercased(r, "not-present")) # => -
print(get_uppercased(r, "testing")) # => FIXED That said; I don't think the offerings of fn's Some actual problems with OptionNo interop with exceptionsWhen I think of try:
x = int(s)
except ValueError:
# do something else In order for It's not much of a monad!I hate to get pedantic, but I think it is generally well-agreed upon that a monad is something which provides at least either one of these two things: (either can be used to implement the other; Option provides neither)
The chaining function goes by many names in other languages; in Haskell it is some funny operator pronounced "bind"; Scala calls it |
@ExpHP I've already figured out that I've played around it for a while and came up with my own purely experimental stuff, which mostly addresses the first and the second issues https://github.com/grayfall/evaluate/blob/master/evaluate/ Here are the important parts
So a user can simply decide which exceptions to catch, which is similar to your proposal. Then I improvised on the monadic functionality
This was supposed to replace the |
@grayfall looks like we're definitely on the same page! That is a neat approach (also, I wasn't aware of F's sugar for partial application)
# suppose 'item' is an optionable version of x[i].
# this gets x[0]['a'] or x[1]['b'], with preference to the former
let f = (Evaluation()
| (item, 0) & (item, 'a')
| (item, 1) & (item, 'b')
)
f([]) # Empty
f([{}]) # Empty
f([{'a': 3}]) # Filled(3)
f([{}, {'b':2}]) # Filled(2)
f([{'a':3}, {'b':2}]) # Filled(3) |
@ExpHP I failed to decide, whether |
@ExpHP using |
I believe the expressed exceptions should always be explicit, which would mean that optionable wrappers must be constructed by the user ahead of time. It would be unfortunate for automatic annotations to hide obvious bugs (such as most NameErrors or AttributeErrors), and also, exceptions may be used for many other things, such as the end of iteration. But not having direct experience using it, I'm not sure how much boilerplate this would actually entail. Edit: To some extent the wrappers can also be constructed on demand by using Evaluation() | (optionable(ValueError)(f), 3) (though maybe optionable could also support the tuple-for-partial shorthand): Evaluation() | optionable(ValueError)(f, 3) This manner of using adapters reminds me of Railway oriented programming | F# for fun and profit, which uses simple function composition together with adapter functions to construct pipelines (as opposed to in Haskell where I find myself using a variety of different types of composition or application; |
@ExpHP Okay, then we've got some serious technical issues to address. If we are going to use the ampersand operator to express the bind operation, we would have to create a class to wrap all nodes in the evaluation to overcome the inability to overload operator precedence in Python. In other words, we would have to end up with a symbolic representation of the entire expression before building the expression object. Alternatively, we can use a lower-precedence operator for the bind operation (e.g. |
Nah, I would want `&` to bind more tightly than `|`. I can't imagine how
the other way around would be as useful.
I just checked was actually fairly surprised to find that `<|>` binds more
tightly than `>>=` in Haskell; to be honest, I feel that is a design flaw!
EDIT: Part of the reason why I would want `&` to bind higher is because `&`
threads the output of one into the next, while `|` duplicates the input for
two functions. So if we are to support multiple arguments to an evaluation
as in the code you posted, then it only works at the outermost level,
and only if that level is `|`.
…On Mon, Feb 13, 2017 at 9:11 AM, Eli ***@***.***> wrote:
@ExpHP <https://github.com/ExpHP> Okay, then we've got some serious
technical issues to address. If we are going to use the ampersand operator
to express the bind operation, we would have to create a class to wrap all
nodes in the evaluation to overcome the inability to overload operator
precedence in Python. In other words, we would have to end up with a
symbolic representation of the entire expression before building the
expression object. Alternatively, we can use a lower-precedence operator
for the bind operation (e.g. >=), but that has its limitations.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#21 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABWI0Dj6Rx-krUuSd82D3mKOeQTVI-cSks5rcGSrgaJpZM4Ki6ip>
.
|
@ExpHP then we need to develop a wrapper, otherwise your expression
will raise a |
...oh. Okay, yes, I see what you mean now. That is a serious issue. :/ (have a simpler idea, will prototype something) |
@ExpHP My idea is to rename
|
@ExpHP Since the
|
@jacobbridges Haven't heard from you for quite a while. Are you still planning to maintain the package? |
@grayfall yes, I still keep track of the issues and what you guys are talking about. My plans are to reorganize the README and make it clear this is a fork; reorganize the tests into separate files which align with the modules; and finally start working towards our version 1 milestone. I've been busy with life stuff like moving and looking for a new job, so I apologize for not adding to these discussions. But I'll be here to review the pull requests when needed. |
Hi @grayfall @ExpHP , are you still working on the issue? |
In the time since this discussion took place I have not used |
@yangyangxcf ok, I'll make a prototype. |
I've been using
fn
for quite some time, so I'm glad you guys are trying to keep it going. Are you planning on implementing that monad? Do you need any contributions?The text was updated successfully, but these errors were encountered: