Dartz - Functional programming in Dart

Overview

dartz

License Pub.dev Github Stars

Functional programming in Dart

  • Type class hierarchy in the spirit of cats, scalaz and the standard Haskell libraries
  • Immutable, persistent collections, including IVector, IList, IMap, IHashMap, ISet and AVLTree
  • Option, Either, State, Tuple, Free, Lens and other tools for programming in a functional style
  • Evaluation, a Reader+Writer+State+Either+Future swiss army knife monad
  • Type class instances (Monoids, Traversable Functors, Monads and so on) for included types, as well as for several standard Dart types
  • Conveyor, an implementation of pure functional streaming
  • Examples, showcasing core concepts
New to functional programming?

A good place to start learning is the excellent Functional Programming in Scala by Paul Chiusano and Rúnar Bjarnason. I can not recommend this book highly enough.
You can also take a look at Category Theory for Programmers by Bartosz Milewski.

Status
  • Starting with version 0.10.0, Dart 2.12+ is required
  • 0.9.x supports Dart 1 and older Dart 2 versions
  • Basic type class structure and collection classes are relatively stable, but might see restructuring in future releases
  • Optimized for dart2js/node/v8, with performance on the dart vm being of distant secondary concern
  • Most things are stack safe and reasonably efficient, but there are a couple of exceptions and plenty of room for further optimizations
  • The streaming/conveyor stuff is highly experimental
  • The lens implementation is experimental and very bare bones
License/Disclaimer

See LICENSE

Comments
  • Use Either with then() and catchError()

    Use Either with then() and catchError()

    I want to use Either in this way:

    Either<Failure, MyResponse> result = await restClient.request() // Future<MyResponse> request();
        .then((response) => Right(response))
        .catchError((failure) => Left(Failure()));
    

    But it seems that I can't do this:

    error: A value of type 'Right< dynamic, MyResponse>' can't be assigned to a variable of type 'Either< Failure, MyResponse>'.

    I necessarily need to use explicit type casting, like this:

    Either<Failure, MyResponse> result = await restClient.request() // Future<MyResponse> request();
        .then((response) => Right(response))
        .catchError((failure) => Left(Failure())) as Either<Failure, MyResponse>; 
    

    even if I already return Left(Failure()) in the catchError(). So, is explicit casting the most concise and elegant solution?

    opened by konstantin-doncov 15
  • Task and Future

    Task and Future

    Hi spebbe,

    In the first place, I want to thank you to bring functional programing to Dart. However I have a question related to Task and Future. If you got time to take a look at my problem I will be thankfull.

    I am running this code with no success and I don't have any clue left.

    Task<Option<Product>> getProduct(int id) =>
          Task(() => this.httpClient.get(someUrl))
            .map((resp) => Some(ProductFromResp(resp)));
    

    As I understand in this case Task takes a Function0 Future<Response> as a parameter and map the http response to produce an Option<Product>. However when I explicitly run getProduct(id).run() the task it doesn't seem to be fired.

    Am I missing something ?

    Regards

    opened by rlavolee 12
  • Provide const constructors for

    Provide const constructors for "empty" - e.g. Option none and IList nil

    I would like to add default values to optional function parameters such as:

    void process([Option<X> param = none()]) { ... }
    

    This results in the error Default values of an optional parameter must be constant.

    Enhancement request - add "const constructors" to dartz for simple "empty" values such as Option none and IList nil.

    My current error prone workaround is to leave the default as null and use the "if null" operator ?? to replace the parameter param ?? none().

    opened by rich-j 12
  • Monad transformers

    Monad transformers

    First of all, thanks for such extensive library. Usually it’s helpful to use a Reader<Future> monad stack to:

    • inject dependencies
    • perform asynchronous operations
    • and return either a result or an error

    Is it possible to achieve this in dartz?

    opened by RPallas92 12
  • Support for Result<T,E> for returning Ok, Err

    Support for Result for returning Ok, Err

    Hi,

    I wondered if anybody has considered having a Result - similar to Either but already has Ok, Err constructs.

    More info here https://github.com/hqoss/monads/tree/master/lib/result. (typescript implementation)

    and original rust implementation https://doc.rust-lang.org/std/result/enum.Result.html

    Cheers

    opened by iangregsondev 9
  • Testing with Either

    Testing with Either

    Hi, I'm currently working on a clean architecture project using Flutter. I find dartz package is useful to bring either success or failure values.

    But, i have issues when it comes to testing.

    This is is my test case which won't passed:

    test('should load list of cast from repository', () async {
        // arrange
        final tId = 1;
        final tCast = Cast(...);
        final tCastList = <Cast>[tCast];
    
        when(mockCreditsRepository.loadCastByMovie(tId))
            .thenAnswer((_) async => Right(<Cast>[tCast]));
        // act
        final result = await usecase.execute(tId);
        // assert
        expect(result, Right(<Cast>[tCast]));
    });
    

    Those test will return as follows:

    Expected: Right<dynamic, List<Cast>>:<Right([Cast(1, department, name, originalName, 0.0, profilePath, character)])>
      Actual: Right<Failure, List<Cast>>:<Right([Cast(1, department, name, originalName, 0.0, profilePath, character)])>
    

    But, somehow it passed when I put both value in the same variable.

    final tCastList = <Cast>[tCast];
    
    when(mockCreditsRepository.loadCastByMovie(tId))
            .thenAnswer((_) async => Right(tCastList));
        // act
        final result = await usecase.execute(tId);
        // assert
        expect(result, Right(tCastList));
    

    I think it is because i create 2 difference instance for the test. Is there a way to evaluate only the value of either instead of comparing the instance?

    opened by LittleFireflies 8
  • Null safe optionOf should accept null

    Null safe optionOf should accept null

    The Option method optionOf needs to accept a nullable value since its function is to remove said null...

    Option<A> optionOf<A>(A? value) => value != null ? some(value) : none();
    

    Using dartz: ^0.10.0-nullsafety.0

    opened by rich-j 8
  • Dart 2.x strong mode causes IList Nil to throw a runtime CastError

    Dart 2.x strong mode causes IList Nil to throw a runtime CastError

    I'm a Scala developer who's starting to use Dart and am excited to see your dartz library. I'm living on the bleeding edge and using Dart 2.0.0-dev.39.0. Option and Either work but when I try to use IList I get a runtime CastError. For example, this code from you test suite final l1 = ilist([1,2,3,4]); compiles okay but throws the following error when compiled for Dart Angular with DDC and running in Chrome:

    _js_helper.CastErrorImplementation.new {message: "CastError: Casting value of type '_Nil' to type 'IList<int>' which is incompatible in strong mode"
    

    I've tried other variations of using IList but all result in the above error.

    Edit: The runtime CastError also happens for Option None, however I can explicitly cast the object creation like Option<String> s4 = new None<String>();. This cast isn't possible for Nil since the _Nil class constructor is private.

    Maybe this issue is a more general question of when do you expect to be Dart 2.x compatible?

    opened by rich-j 8
  • Updating test package version to 0.17.1

    Updating test package version to 0.17.1

    Can you please merge this PR and publish the release version of dartz to pub? the test plugin version has been changed to the released version and flutter test runs correctly:

    flutter test
    Changing current working directory to: /home/idelub/Repository/Flutter/forks/dartz
    Running "flutter pub get" in dartz...                              43.3s
    00:02 +258: All tests passed!
    

    Thanks

    opened by arnaudelub 7
  • 2nd API depends on 1st API - how can I do this?

    2nd API depends on 1st API - how can I do this?

    I need some help here. I learned this library from this tutorial https://resocoder.com/2019/12/14/functional-error-handling-in-flutter-dart-2-either-task-fp/ and single API call seemed to work.

    However I have this scenario

    1st API - https://ip/v1/programs - this API will return all programs

    Then, in order to get the programs' photo, I need to call another API and do a for loop.

    2nd API - https://ip/v1/programs/id/photo - the id is passed from 1st API and photo is in binary bytes

    Basically I need to call 2nd API after I call 1st API. Then assign the photo into each program from the List return from 1st API.

    Note: program.dart (used freezed package) and it's immutable. Has id, photo, etc fields.

    My codes

    Either<NetworkExceptions, List<Program>> _result;
      Either<NetworkExceptions, List<Program>> get result => _result;
      void _setResult(Either<NetworkExceptions, List<Program>> result) {
        _result = result;
      }
    
    Future<void> getPrograms() async {
    await Task(() => _service.getPrograms(token))
    .attempt()
    .mapLeftToFailure()
    .run()
    .then((value) => _setResult(value));
    
    result.fold(
    (failure) => {}
    (programs) async {
    // call 2nd API here ???
    }
    );
    
    Future<List<Program>> getProgramPhoto(Token token, List<Program> old) async {
    List<Program> newProgram;
    
    old.forEach(
    (program) async {
     await Task(() => _service.getProgramPhoto(token, program.id))
    .attempt()
    .mapLeftToFailure()
    .run()
    .then((value) => ??);
    }
    );
    }
    

    Questions

    1. Not sure the way I write my codes is correct. Any idea?
    2. Any idea how do I assign photo (Uint8List) to an existing List as Program is immutable?
    opened by ericchuawc 7
  • Flutter StatefulWidget State name collision

    Flutter StatefulWidget State name collision

    Since today in my Android Studio the dart compiler values the dartz import more than the material.dart import so I have to use

    import 'package:dartz/dartz.dart' as dz;
    

    when I want to use a StatefulWidget and some dartz objects or functions. Otherwise the app doesn't compile and throws this error message:

    Compiler message:
    lib/main.dart:31:32: Error: Expected 0 type arguments.
    class _HomeWidgetState extends State<HomeWidget> {
                                   ^
    lib/main.dart:28:20: Error: The return type of the method 'HomeWidget.createState' is '_HomeWidgetState', which does not match the return type, 'State<StatefulWidget>', of the overridden method, 'StatefulWidget.createState'.
     - '_HomeWidgetState' is from 'package:stock_check/main.dart' ('lib/main.dart').
     - 'State' is from 'package:flutter/src/widgets/framework.dart' ('/C:/src/flutter/packages/flutter/lib/src/widgets/framework.dart').
     - 'StatefulWidget' is from 'package:flutter/src/widgets/framework.dart' ('/C:/src/flutter/packages/flutter/lib/src/widgets/framework.dart').
    Change to a subtype of 'State<StatefulWidget>'.
      _HomeWidgetState createState() => _HomeWidgetState();
    
    
    
    
    opened by torbenkeller 7
  • Feature request: Either as left and right

    Feature request: Either as left and right

    In the following scenario

    https://stackoverflow.com/questions/75007868/with-dartz-is-it-possible-to-pass-a-failure-on-to-the-function-that-is-folding-m/75008089#75008089

    it would be great to have an asLeft and asRight as was proposed in the answer.

    Future<Either<Failure, AuthUser>> call() async {
        final userResponse = await _authRepository.getUser();
    
        if(userResponse.isLeft()){
           // do your stuffs       
         }
    

    Inside this, you may like to access data directly, this extension will help

    extension EitherX<L, R> on Either<L, R> {
      R asRight() => (this as Right).value; //
      L asLeft() => (this as Left).value;
    }
    
    opened by duck-dev-go 3
  • How to cast both sides of Either?

    How to cast both sides of Either?

    I am trying to have Either<Failure, Concrete> where Concrete extends Abstract class, but I cannot get it to work. If I try to cast the left side I get the error:

    type 'Right<Failure, Concrete>' is not a subtype of type 'Either<Failure, Abstract>' in type cast
    

    if I try for the right side I get:

    type 'Left<Object, Concrete>' is not a subtype of type 'Either<Failure, Concrete>' in type cast
    

    And bimap does not seems to solve it. Is there an easy way to do it? tks

    opened by jalvespinto 0
  • Comment indicates side effect in method where none exists

    Comment indicates side effect in method where none exists

    In the option.dart file a comment suggests that the code below the comment has side effects.

    // PURISTS BEWARE: side effecty stuff below -- proceed with caution!

    One Method there is the toNullable() method.

    It looks like that:

    A? toNullable() => fold(() => null, id);
    

    This method does not seem to create a side effect and therefore it should be above the stated comment to avoid confusion.

    I would create a PR that moves the method upwords, so that it is above the comment. Would this PR be merged?

    opened by ju851zel 0
  • Enable github discussions?

    Enable github discussions?

    I'm not sure if enough people would participate to make it work out, but it might be nice to enable Discussions so there is a place to ask for advice without creating an issue.

    opened by jibbers42 0
  • Async issue when using mаp()

    Async issue when using mаp()

    Unhandled Exception: 'package:bloc/src/emitter.dart': Failed assertion: '!_isCompleted'

    emit was called after an event handler completed normally. This is usually due to an unawaited future in an event handler. Please make sure to await all asynchronous operations with event handlers and use emit.isDone after asynchronous operations before calling emit() to ensure the event handler has not completed.

    BAD on((event, emit) { future.whenComplete(() => emit(...)); });

    GOOD on((event, emit) async { await future.whenComplete(() => emit(...)); });

    failureOrToken.map((token) async {
            final failureOrProfile =
                await profileRepository.getCurrentUserProfile(token);
            failureOrProfile.map(
              (profile) async {
                final failureOrTeams = await teamsRepository.getTeams(token);
                failureOrTeams.map(
                  (teams) async {
                    final failureOrLocations =
                        await locationsRepository.getLocations(token);
                    failureOrLocations.map(
                      (locations) => emit(
                        SuccessState(
                          profile: profile,
                          teams: teams,
                          locations: locations,
                        ),
                      ),
                    );
                  },
                );
              },
            );
          },
        ).leftMap(
          (failure) => emit(
            ErrorState(
              message: mapFailureToMessage(failure),
            ),
          ),
        );
    
    opened by ihorkozar 0
Owner
Björn Sperber
Björn Sperber
Random Users app, developed with Flutter and using Clean Architecture, BLoC, TDD and Functional Programming.

random_users This project is a sample of how to build a Flutter application using de benefits of Clean Architecture, TDD and Functional Programming. G

Yago Nunes 3 Jul 21, 2022
Docker images for the Dart programming language (https://dart.dev)

dart-docker This is the Git repo of the Docker "Official Images" for the Dart programming language. See the Docker Hub page for a full description on

Dart 49 Dec 14, 2022
(Full-stack) Fully functional social media app (Instagram clone) written in flutter and dart with backend node.js and Postgres SQL.

Photoarc A Fully functional social media app written in flutter and dart using node.js and Postgres SQL as backend. Backend Repository Demo Download t

Ansh rathod 59 Jan 5, 2023
Functional extensions to Dart collections.

collection_ext A set of extension methods for Dart collections, designed for the purpose of making it easier to write concise, functional-programming-

Yingxin Wu 7 Nov 21, 2022
Dart port of FormCoreJS: A minimal pure functional language based on self dependent types.

FormCore.js port to Dart. So far only the parser and typechecker have been ported i.e. the FormCore.js file in the original repo. (Original readme fro

Modestas Valauskas 2 Jan 28, 2022
Kenso - A fully functional social media app with multiple features built with flutter and dart

Kenso - Social Media App Kenso is a fully functional social media app with multi

null 0 Feb 8, 2022
Intel Corporation 238 Dec 24, 2022
This repository was created to provide the basics of the Dart programming language and Its use cases.

dart-exercises A collection of source code of the Dart Programming language. How does this repository works? Clone / Fork this repository to make your

Technosoft Labs 2 Oct 28, 2021
Repo for Teach Yourself mastering dart programming language

mastering-dart Repo for Teach Yourself mastering dart programming language Chapter Membuat Aplikasi Pertama Menggunakan Dart Percabangan Perulangan Fu

Feri Lukmansyah 50 Nov 10, 2022
Dart programming learning Files

dart_programming A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you started

This is Varma 0 Nov 23, 2021
App concept created with Flutter using Dart programming language, inspired by Groceries Shopping App Interaction.

Grocery Shop Flutter App concept created with Flutter using Dart programming language, inspired by Groceries Shopping App Interaction. About The app w

Wilton Neto 485 Dec 9, 2022
The component created with Flutter using Dart programming language, inspired in Fluid Slider by Ramotion.

Fluid Slider Flutter The component created with Flutter using Dart programming language, inspired in Fluid Slider by Ramotion. About The component was

Wilton Neto 41 Sep 30, 2022
Flutter component concept created with Flutter using Dart programming language, inspired by Gooey Rab Bar.

Gooey Tab Bar Flutter Flutter component concept created with Flutter using Dart programming language, inspired by Gooey Tab Bar. About This component

Wilton Neto 216 Dec 14, 2022
Learn Dart Programming, its basics and Fundamentals from scratch.

Dart Programming Tutorial for Beginners Learn Dart Programming, its basics and Fundamentals from scratch. Topics to be covered Overview Course introdu

Sriyank Siddhartha 696 Jan 7, 2023
Implementation of data structures and algorithms in Dart programming language.

Algorithms in Dart Implementation of several algorithms with Dart programming language. Use dartdoc to generate documentation. Lists List data structu

Mafinar Khan 197 Dec 24, 2022
🇮🇪 A generic programming language interpreter, linter, formatter, and all that jazz, written in Dart.

Irishman ???? A generic programming language interpreter, linter, formatter, and all that jazz, written in Dart. Installation To install this package

Fairfield Programming Association 2 Oct 8, 2022
Fan-made, handmade, recursive-descent parser for the Dart programming language.

Very Unofficial Parser Fan-made, handmade, recursive-descent parser for the Dart programming language. Although this parser strives to parse the langu

Joanna May 64 Nov 21, 2022
A fully functional social media app built with flutter with multiple features

?? ?? Wooble Social Media App Wooble is a fully functional social media app with multiple features built with flutter and dart. Star ⭐ the repo if you

Success Charles 562 Jan 3, 2023