Expression/Monads

From FlexRule Wiki
(Redirected from Expression/Pipes)
Jump to: navigation, search

Introduction

Monads

Monads are functions that can be chained together, which means the output of the previous one can be the input of the next one. The binding operator of monads is Pipe (i.e., |)

Fr-pipe-ops.png

Pipe is an operator that enables the chaining of monads' results and produces a new result that may have a new type.

input |MonadName (arg1, arg2, arg3...)

As you can see in the above format, it has a name and a list of arguments which may be either optional or mandatory.

The power of Pipe is in its chaining capability at the expression level.

input |monad1 (a1, a2, a3, ...)
      |monad2 (b1, b2, b3, ...)
      |monad3 (c1, c2, c3, ...)
      ...

This has the following benefits:

  • Eliminates the need for introducing multiple expressions and assignment evaluations
  • Allows the evaluation of complex multi-line expressions in as a single unit of execution (no nested rule commands for the evaluation of complex logic)

As a result, the logic model will be significantly simpler.

For instance, let's say you have an input parameter named input in which you need to:

  1. apply func1 and then
  2. apply func2 with the input of func1's result

So instead of executing these two:

  1. a = func1(input, 1, 2, 3)
  2. b = func2(a, 4, 5, 6)

You can execute this one:

b = input |func1 (1, 2, 3) |func2 (4, 5, 6)

For a real example, have a look at identifying duplicates on this page.

Supporting Platforms

In the front of each Monadic operator, you can see the icons below, each of which each indicates the supported platform of the monad.

  • FlexRule Engine in .Net Platforms: This monad is supported on any .Net platform in which RuntimeEngine is integrated and runs the logic.
  • JavaScript Platforms: This monad is supported on the JavaScript platform.

API

Please check the Monad API list

Monad101

Do you need more examples and sample expressions? Visit Monad101

Quick Samples

Identifying Duplicates

Let's say we have the following list:

Name Age Sex
Arash 38 Male
Parsa 6 Male
Arash 38 Male
Pooya 3 Male
Shah 3 Female
Shah 31 Male

Example 1: Name Duplication

Sample: people 
        |groupBy(p, p.Name) 
        |where (g, g.Count>1)
        |select (d, d.Key)
Result: List of people names that are duplicated
Name
Arash
Shah


Example 2: Name and Sex Duplication (A person is duplicated when Name and Sex are the same)

Sample: people 
        |groupBy (p, key(p.Name, p.Sex)) 
        |where (g, g.Count>1)
        |select (d, d.Key.Name)
Result: List of names that are duplicated
Name
Arash

Complex Data Processing

If we have the following data and would like to split it into two sections:

Cars-data-question.png

We have other versions of this at this example.

The other way is to use pure monadic expressions and solve it in two steps;

 /* intersections */
 allUniqueCars = cars |filter (thisCar, 
                         cars |count(otherCar, 
                           (otherCar.Make == thisCar.Make) and (otherCar.Model == thisCar.Model)) 
                         == cars|distinct(g, g.Group)|count()
                           )
                    |distinct(x, x.Make, x.Model);
                     
 /* differences */
 commonCars = cars |filter (thisCar, 
                         cars |count(otherCar, 
                           (otherCar.Make == thisCar.Make) and (otherCar.Model == thisCar.Model)) 
                           == 1
                           )
                    |distinct(x, x.Make, x.Model);