Skip to content

Instantly share code, notes, and snippets.

@ebwood
Created February 1, 2024 13:31
Show Gist options
  • Select an option

  • Save ebwood/d5e9fd834abddcd9d7a39f8bbead6585 to your computer and use it in GitHub Desktop.

Select an option

Save ebwood/d5e9fd834abddcd9d7a39f8bbead6585 to your computer and use it in GitHub Desktop.
dart curry and uncurry using operator overload
// function void
typedef FunctionVoid = void Function();
// function0
typedef Function0<T> = T Function();
// function1
typedef Function1<T, A> = T Function(A a);
// uncurry function2
typedef UncurryFunction2<T, A, B> = T Function(A a, B b);
// uncurry function3
typedef UncurryFunction3<T, A, B, C> = T Function(A a, B b, C c);
// uncurry function4
typedef UncurryFunction4<T, A, B, C, D> = T Function(A a, B b, C c, D d);
// uncurry function5
typedef UncurryFunction5<T, A, B, C, D, E> = T Function(
A a, B b, C c, D d, E e);
// uncurry function6
typedef UncurryFunction6<T, A, B, C, D, E, F> = T Function(
A a, B b, C c, D d, E e, F f);
// uncurry function7
typedef UncurryFunction7<T, A, B, C, D, E, F, G> = T Function(
A a, B b, C c, D d, E e, F f, G g);
// uncurry function8
typedef UncurryFunction8<T, A, B, C, D, E, F, G, H> = T Function(
A a, B b, C c, D d, E e, F f, G g, H h);
// uncurry function9
typedef UncurryFunction9<T, A, B, C, D, E, F, G, H, I> = T Function(
A a, B b, C c, D d, E e, F f, G g, H h, I i);
// uncurry function10
typedef UncurryFunction10<T, A, B, C, D, E, F, G, H, I, J> = T Function(
A a, B b, C c, D d, E e, F f, G g, H h, I i, J j);
extension FunctionVoidExtension on FunctionVoid {
FunctionVoid composite0(FunctionVoid func) => () {
this();
func();
};
FunctionVoid operator *(FunctionVoid func) => composite0(func);
}
extension Function1Extension<T, A> on Function1<T, A> {
T operator <<(A a) => this(a);
Function1<T, B> composite1<B>(Function1<A, B> func) => (B b) => this(func(b));
Function0<T> composite0(Function0<A> func) => () => this(func());
Function0<T> operator *(Function0<A> func) => composite0(func);
Function1<T, A> get curry => this;
Function1<T, A> get uncurry => this;
}
extension UncurryFunction2Extension<T, A, B> on UncurryFunction2<T, A, B> {
Function1<T, B> operator <<(A a) => (B b) => this(a, b);
CurryFunction2<T, A, B> get curry => (A a) => (B b) => this(a, b);
}
extension UncurryFunction3Extension<T, A, B, C>
on UncurryFunction3<T, A, B, C> {
UncurryFunction2<T, B, C> operator <<(A a) => (B b, C c) => this(a, b, c);
CurryFunction3<T, A, B, C> get curry =>
(A a) => (B b) => (C c) => this(a, b, c);
}
extension UncurryFunction4Extension<T, A, B, C, D>
on UncurryFunction4<T, A, B, C, D> {
UncurryFunction3<T, B, C, D> operator <<(A a) =>
(B b, C c, D d) => this(a, b, c, d);
CurryFunction4<T, A, B, C, D> get curry =>
(A a) => (B b) => (C c) => (D d) => this(a, b, c, d);
}
extension UncurryFunction5Extension<T, A, B, C, D, E>
on UncurryFunction5<T, A, B, C, D, E> {
UncurryFunction4<T, B, C, D, E> operator <<(A a) =>
(B b, C c, D d, E e) => this(a, b, c, d, e);
CurryFunction5<T, A, B, C, D, E> get curry =>
(A a) => (B b) => (C c) => (D d) => (E e) => this(a, b, c, d, e);
}
extension UncurryFunction6Extension<T, A, B, C, D, E, F>
on UncurryFunction6<T, A, B, C, D, E, F> {
UncurryFunction5<T, B, C, D, E, F> operator <<(A a) =>
(B b, C c, D d, E e, F f) => this(a, b, c, d, e, f);
CurryFunction6<T, A, B, C, D, E, F> get curry => (A a) =>
(B b) => (C c) => (D d) => (E e) => (F f) => this(a, b, c, d, e, f);
}
extension UncurryFunction7Extension<T, A, B, C, D, E, F, G>
on UncurryFunction7<T, A, B, C, D, E, F, G> {
UncurryFunction6<T, B, C, D, E, F, G> operator <<(A a) =>
(B b, C c, D d, E e, F f, G g) => this(a, b, c, d, e, f, g);
CurryFunction7<T, A, B, C, D, E, F, G> get curry => (A a) => (B b) =>
(C c) => (D d) => (E e) => (F f) => (G g) => this(a, b, c, d, e, f, g);
}
extension UncurryFunction8Extension<T, A, B, C, D, E, F, G, H>
on UncurryFunction8<T, A, B, C, D, E, F, G, H> {
UncurryFunction7<T, B, C, D, E, F, G, H> operator <<(A a) =>
(B b, C c, D d, E e, F f, G g, H h) => this(a, b, c, d, e, f, g, h);
CurryFunction8<T, A, B, C, D, E, F, G, H> get curry =>
(A a) => (B b) => (C c) => (D d) =>
(E e) => (F f) => (G g) => (H h) => this(a, b, c, d, e, f, g, h);
}
extension UncurryFunction9Extension<T, A, B, C, D, E, F, G, H, I>
on UncurryFunction9<T, A, B, C, D, E, F, G, H, I> {
UncurryFunction8<T, B, C, D, E, F, G, H, I> operator <<(A a) =>
(B b, C c, D d, E e, F f, G g, H h, I i) =>
this(a, b, c, d, e, f, g, h, i);
CurryFunction9<T, A, B, C, D, E, F, G, H, I> get curry =>
(A a) => (B b) => (C c) => (D d) => (E e) =>
(F f) => (G g) => (H h) => (I i) => this(a, b, c, d, e, f, g, h, i);
}
extension UncurryFunction10Extension<T, A, B, C, D, E, F, G, H, I, J>
on UncurryFunction10<T, A, B, C, D, E, F, G, H, I, J> {
UncurryFunction9<T, B, C, D, E, F, G, H, I, J> operator <<(A a) =>
(B b, C c, D d, E e, F f, G g, H h, I i, J j) =>
this(a, b, c, d, e, f, g, h, i, j);
CurryFunction10<T, A, B, C, D, E, F, G, H, I, J> get curry =>
(A a) => (B b) => (C c) => (D d) => (E e) => (F f) => (G g) =>
(H h) => (I i) => (J j) => this(a, b, c, d, e, f, g, h, i, j);
}
// curry function2
typedef CurryFunction2<T, A, B> = Function1<T, B> Function(A b);
// curry function3
typedef CurryFunction3<T, A, B, C> = CurryFunction2<T, B, C> Function(A b);
// curry function4
typedef CurryFunction4<T, A, B, C, D> = CurryFunction3<T, B, C, D> Function(
A b);
// curry function5
typedef CurryFunction5<T, A, B, C, D, E> = CurryFunction4<T, B, C, D, E>
Function(A b);
// curry function6
typedef CurryFunction6<T, A, B, C, D, E, F> = CurryFunction5<T, B, C, D, E, F>
Function(A b);
// curry function7
typedef CurryFunction7<T, A, B, C, D, E, F, G>
= CurryFunction6<T, B, C, D, E, F, G> Function(A b);
// curry function8
typedef CurryFunction8<T, A, B, C, D, E, F, G, H>
= CurryFunction7<T, B, C, D, E, F, G, H> Function(A b);
// curry function9
typedef CurryFunction9<T, A, B, C, D, E, F, G, H, I>
= CurryFunction8<T, B, C, D, E, F, G, H, I> Function(A b);
// curry function10
typedef CurryFunction10<T, A, B, C, D, E, F, G, H, I, J>
= CurryFunction9<T, B, C, D, E, F, G, H, I, J> Function(A b);
extension CurryFunction2Extension<T, A, B> on CurryFunction2<T, A, B> {
UncurryFunction2<T, A, B> get uncurry => (A a, B b) => this(a)(b);
Function1<T, B> operator <<(A a) => (B b) => this(a)(b);
}
extension CurryFunction3Extension<T, A, B, C> on CurryFunction3<T, A, B, C> {
UncurryFunction3<T, A, B, C> get uncurry => (A a, B b, C c) => this(a)(b)(c);
CurryFunction2<T, B, C> operator <<(A a) => (B b) => (C c) => this(a)(b)(c);
}
extension CurryFunction4Extension<T, A, B, C, D>
on CurryFunction4<T, A, B, C, D> {
UncurryFunction4<T, A, B, C, D> get uncurry =>
(A a, B b, C c, D d) => this(a)(b)(c)(d);
CurryFunction3<T, B, C, D> operator <<(A a) =>
(B b) => (C c) => (D d) => this(a)(b)(c)(d);
}
extension CurryFunction5Extension<T, A, B, C, D, E>
on CurryFunction5<T, A, B, C, D, E> {
UncurryFunction5<T, A, B, C, D, E> get uncurry =>
(A a, B b, C c, D d, E e) => this(a)(b)(c)(d)(e);
CurryFunction4<T, B, C, D, E> operator <<(A a) =>
(B b) => (C c) => (D d) => (E e) => this(a)(b)(c)(d)(e);
}
extension CurryFunction6Extension<T, A, B, C, D, E, F>
on CurryFunction6<T, A, B, C, D, E, F> {
UncurryFunction6<T, A, B, C, D, E, F> get uncurry =>
(A a, B b, C c, D d, E e, F f) => this(a)(b)(c)(d)(e)(f);
CurryFunction5<T, B, C, D, E, F> operator <<(A a) =>
(B b) => (C c) => (D d) => (E e) => (F f) => this(a)(b)(c)(d)(e)(f);
}
extension CurryFunction7Extension<T, A, B, C, D, E, F, G>
on CurryFunction7<T, A, B, C, D, E, F, G> {
UncurryFunction7<T, A, B, C, D, E, F, G> get uncurry =>
(A a, B b, C c, D d, E e, F f, G g) => this(a)(b)(c)(d)(e)(f)(g);
CurryFunction6<T, B, C, D, E, F, G> operator <<(A a) => (B b) =>
(C c) => (D d) => (E e) => (F f) => (G g) => this(a)(b)(c)(d)(e)(f)(g);
}
extension CurryFunction8Extension<T, A, B, C, D, E, F, G, H>
on CurryFunction8<T, A, B, C, D, E, F, G, H> {
UncurryFunction8<T, A, B, C, D, E, F, G, H> get uncurry =>
(A a, B b, C c, D d, E e, F f, G g, H h) => this(a)(b)(c)(d)(e)(f)(g)(h);
CurryFunction7<T, B, C, D, E, F, G, H> operator <<(A a) => (B b) => (C c) =>
(D d) => (E e) => (F f) => (G g) => (H h) => this(a)(b)(c)(d)(e)(f)(g)(h);
}
extension CurryFunction9Extension<T, A, B, C, D, E, F, G, H, I>
on CurryFunction9<T, A, B, C, D, E, F, G, H, I> {
UncurryFunction9<T, A, B, C, D, E, F, G, H, I> get uncurry =>
(A a, B b, C c, D d, E e, F f, G g, H h, I i) =>
this(a)(b)(c)(d)(e)(f)(g)(h)(i);
CurryFunction8<T, B, C, D, E, F, G, H, I> operator <<(A a) =>
(B b) => (C c) => (D d) => (E e) =>
(F f) => (G g) => (H h) => (I i) => this(a)(b)(c)(d)(e)(f)(g)(h)(i);
}
extension CurryFunction10Extension<T, A, B, C, D, E, F, G, H, I, J>
on CurryFunction10<T, A, B, C, D, E, F, G, H, I, J> {
UncurryFunction10<T, A, B, C, D, E, F, G, H, I, J> get uncurry =>
(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) =>
this(a)(b)(c)(d)(e)(f)(g)(h)(i)(j);
CurryFunction9<T, B, C, D, E, F, G, H, I, J> operator <<(A a) =>
(B b) => (C c) => (D d) => (E e) => (F f) => (G g) =>
(H h) => (I i) => (J j) => this(a)(b)(c)(d)(e)(f)(g)(h)(i)(j);
}
void main() {
final uncurryF = test;
print(uncurryF);
print(uncurryF << 10);
print(uncurryF << 10 << 20.0);
print(uncurryF << 10 << 20.0 << 'abc');
final curryF = test.curry;
print(curryF);
print(curryF << 10 << 20.0);
print(uncurryF << 10 << 20.0 << 'abc');
final UncurryFunction3Class uncurryFunction3Class = UncurryFunction3Class();
print(uncurryFunction3Class
is UncurryFunction3<dynamic, dynamic, dynamic, dynamic>);
}
String test(int a, double? b, String? c) => '$a $b $c';
class UncurryFunction3Class<T, A, B, C> {
T call(A a, B b, C c) {
throw UnimplementedError();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment