lloydmeta / frunk

Funktional generic type-level programming in Rust: HList, Coproduct, Generic, LabelledGeneric, Validated, Monoid and friends.
https://beachape.com/frunk/
MIT License
1.28k stars 58 forks source link

Implement folds for references #181

Open ImmemorConsultrixContrarie opened 3 years ago

ImmemorConsultrixContrarie commented 3 years ago

Closes #180.

Things to do before this draft PR could be made an actual PR:

Bikeshedding and doc changes will be part of another PR: https://github.com/lloydmeta/frunk/pull/181#issuecomment-845617332

ImmemorConsultrixContrarie commented 3 years ago

Funny fact: inherent foldl method does not interfere with (&hlist).foldl or (&mut hlist).foldl calls. However, I still think that we should remove or rename the inherent methods; due to the same names for methods in struct and in trait, compiler could emit some misleading errors

lloydmeta commented 3 years ago

Since there's no conflict, I would prefer that we keep this PR to just implementing the fold methods for references.

IMO, if the user is using the "wrong" folder "function" with a given binding (e.g. hlist value but folder expects references), then they should get an error, which is the same as if you pass a reference-expecting closure when .maping over a vec.into_iter(): there is no separate map_val or map_mut.

ExpHP commented 3 years ago

However, I still think that we should remove or rename the inherent methods; due to the same names for methods in struct and in trait, compiler could emit some misleading errors

I'm not at all keen on removing them, as I feel this can hurt discoverability. Having them there gives us this; the whole API of HLists documented on a single page, in precisely the form that we are used to consuming documentation in as rustaceans. Prior to 2.0, the closest you could get was to look at examples in README.md or on the hlist module—or to look at the traits in the docs, which were scary.

I would go so far as to say I'd rather have three inherent methods (foldl, foldl_ref, foldl_mut), and if I were to rename anything I'd rename the trait method to either foldl_ or foldl_generic. But this could be a slippery slope; there are other methods that could use _ref and _mut variants, yet obviously it'd be crazy to add these variants for all methods. (probably just maps and folds?). But personally this is why I've been satisfied with just having orthogonal to_ref()/to_mut() methods.

redbaron commented 1 year ago

Been hit by the lack of folding on reference. I know it's been a while, but maybe there is a way forward to merge it? :)