Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .idea/.gitignore

This file was deleted.

Binary file not shown.
26 changes: 26 additions & 0 deletions tutorial/step_2_business_language/elm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"elm-explorations/test": "1.2.2"
},
"indirect": {
"elm/json": "1.1.3",
"elm/random": "1.0.0",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.2"
}
},
"test-dependencies": {
"direct": {},
"indirect": {}
}
}
10 changes: 10 additions & 0 deletions tutorial/step_2_business_language/morphir.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "Morphir.Example.App",
"sourceDirectory": "src",
"exposedModules": [
"App",
"Forecast",
"Rentals",
"Winds"
]
}
72 changes: 72 additions & 0 deletions tutorial/step_2_business_language/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Morphir Tutorial: First Logic Model

We'll start out with a very simple example of modeling logic: whether we have enough surfboards to satisfy a rental request. First up, let's create the Elm source file for our code.

First create the file ```src/Morphir/Examples/App/Rentals.elm```. In linux that's:

```
mkdir src/Morphir
mkdir src/Morphir/Examples
mkdir src/Morphir/Examples/App
touch src/Morphir/Examples/App/Rentals.elm
```

We need to update ```morphir.json``` to reflect our new module. Edit it to add the ```Morphir.Example.App``` package and the ```Rentals``` module and like this:

```
{
"name": "Morphir.Example.App",
"sourceDirectory": "src",
"exposedModules": [
"Rentals"
]
}
```

Now edit the ```Rentals.eml``` file. First, we want to reflect the module (aka namespace). Add:

``` Elm
module Morphir.Example.App.Rentals exposing (..)


```

That takes care of the boilerplate. Now we can focus on the business logic. We'll put that into a function:

``` Elm
request : Int -> Int -> Result String Int
request availability requestedQuantity =
if requestedQuantity <= availability then
Ok requestedQuantity
else
Err "Insufficient availability"
```
This is Elm's way of declaring a function. In this case, the function takes the current availability and the requested amount and returns a Result, which is either the quantity to be rented or an error message. At this point, we might want to play around to test that we got everything covered. We can do this with Morphir's developer tools. On the command line, type:

```
morphir-elm make
morphir-elm develop
```

Go ahead and click on the http://0.0.0.0:3000 link (note: you can also find an online example at [Insight Sample](https://finos.github.io/morphir-service)). Click on the "Rentals" link. You should see a page like:

<img src="developer_page_1.png" />

We can test out our logic by trying different values and checking the execution paths below:

<img src="developer_page_2.png" /><img src="developer_page_3.png" />

### Generating code
You might be interested in using this logic in a larger application. One option is to use the base Scala generator to transpile to a Scala library. This would allow you to use it as you would any other Scala library. To generate into the ```dist``` folder default, run:

```
morphir-elm gen
```

The full source code for the model can be found at [Rentals.elm](src/Morphir/Example/App/Rentals.elm)

That wraps up our first Morphir model!



[Home](../../readme.md) | [Prev](../../install.md) | [Next](step_2_refined_logic/readme.md)
25 changes: 25 additions & 0 deletions tutorial/step_2_business_language/src/Morphir/Example/App/App.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Morphir.Example.App.App exposing (..)

import Morphir.Example.App.Forecast exposing (..)
import Morphir.Example.App.Rentals exposing (..)
import Morphir.Example.App.Winds exposing (..)


processRequest : Forecast -> CurrentInventory -> ExistingReservations -> PendingReturns -> RequestedQuantity -> AllowPartials -> Result Reason ReservedQuantity
processRequest forecast inventory reservations returns requestedQuantity allowPartials =
let
windCategory : WindCategory
windCategory =
categorizeWindForForecast forecast
in
decide windCategory forecast.shortForcast inventory reservations returns requestedQuantity allowPartials


categorizeWindForForecast : Forecast -> WindCategory
categorizeWindForForecast forecast =
let
windCategory : WindCategory
windCategory =
categorizeWind forecast.windSpeed.max
in
windCategory
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module Morphir.Example.App.Forecast exposing (..)


type alias MPH =
Int


type WindDirection
= North
| South
| East
| West


type alias Celcius =
Int


type ForecastDetail
= Showers
| Thunderstorms
| Snow
| Fog


type alias ForecastPercent =
Float


type alias Forecast =
{ temp : { low : Celcius, high : Celcius }
, windSpeed : { min : MPH, max : MPH }
, windDirection : WindDirection
, shortForcast : ForecastDetail
, forecastPercent : ForecastPercent
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
module Morphir.Example.App.Rentals exposing (..)

import Morphir.Example.App.Forecast exposing (..)
import Morphir.Example.App.Winds exposing (..)


type alias CurrentInventory =
Int


type alias ExistingReservations =
Int


type alias PendingReturns =
Int


type alias RequestedQuantity =
Int


type alias ReservedQuantity =
Int


type alias Availability =
Int


type alias AllowPartials =
Bool


type Reason
= InsufficientAvailability
| ClosedDueToConditions


type ExpertiseLevel
= Novice
| Intermediate
| Expert


decide : WindCategory -> ForecastDetail -> CurrentInventory -> ExistingReservations -> PendingReturns -> RequestedQuantity -> AllowPartials -> Result Reason ReservedQuantity
decide windCategory forecastDetail inventory reservations returns requestedQuantity allowPartials =
let
isClosed : Bool
isClosed =
case ( windCategory, forecastDetail ) of
( DangerousWinds, _ ) ->
True

( _, Thunderstorms ) ->
True

_ ->
False

availability : Availability
availability =
inventory - reservations + returns
in
if isClosed then
Err ClosedDueToConditions

else if requestedQuantity <= availability then
Ok requestedQuantity

else if allowPartials then
Ok availability

else
Err InsufficientAvailability
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Morphir.Example.App.Winds exposing (..)

import Morphir.Example.App.Forecast exposing (..)


type WindCategory
= Calm
| Windy
| HighWinds
| DangerousWinds


categorizeWind : Int -> WindCategory
categorizeWind windSpeed =
if windSpeed < 10 then
Calm

else if windSpeed < 20 then
HighWinds

else if windSpeed < 30 then
Windy

else
DangerousWinds