Simplee.IO 1.0.6

There is a newer version of this package available.
See the version list below for details.
dotnet add package Simplee.IO --version 1.0.6                
NuGet\Install-Package Simplee.IO -Version 1.0.6                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Simplee.IO" Version="1.0.6" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Simplee.IO --version 1.0.6                
#r "nuget: Simplee.IO, 1.0.6"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Simplee.IO as a Cake Addin
#addin nuget:?package=Simplee.IO&version=1.0.6

// Install Simplee.IO as a Cake Tool
#tool nuget:?package=Simplee.IO&version=1.0.6                

Koio |> Simple.IO

Library Simplee.IO v1.0.6 implements common IO functionality used by all other Simple projects. The namespace of the library is Simplee.IO.

    open Simplee.IO

Here is the main functionality exposed:

  1. Stack free monad
  2. Queue free monad
  3. Reader monad
  4. State monad
  5. Writer monad

1. Stack

1.1 The Free Monad

The library exposes a free monad for stack operations. The stack monad comes with 3 instructions:

  1. push instruction which pushes a value on top of the stack
  2. pop instruction which extracts the value from the top of the stack
  3. peek instruction which returns the value from the top of the stack without removing it from the stack.

The instructions use the error type provided in Simplee.Common package in order to return the evantual failures.

1.2 Computation Builder

This monad is wrapped within stk, a computation expression builder.

The user can construct flows into an imperative way using this builder.

    let flow = stk {
        let! _ = stkpush 10
        let! _ = stkpeek ()
        let! r = stkpop ()
        return r
        }
1.3 Built-in Interpreters

The flows generated with the builder can be interpreted using built-in interpretors. The library provides two interpretors:

  1. stklstr - an interpretor that transfors a flow of instructions into a listing.
  2. stkim - an interpretor that implements an in-memory stack which can have or not an upper limit.

Here is an example for the stack lister:

    flow
    |> stklst (fun () -> 10)
    |> List.iter (lstrln2str >> printfn "%s")

And here is an example for the in-memory stack:

    flow
    |> stkimrun (stkimE 10)        // start with an empty stack with upper limit set to 10
    |> fst
    |> printfn "Stack: %O"

There are several convenience function which can create an in-memory stack: stkimEU, stkimE, stkimA where you can set the upper limit of the stack and/or the initial values in the stack.

1.4 User-Defined Interpreters

A user can implement its own interpreter (eg. the stack is implemented on a database). The user will have to implement push, pop, peek, and pur functions, which stand for each of the stack instructions and for the function that return the final result of the workflow.

One of the arguments for these functions is the state instance which can be used to pass and or reuse information from one instruction to the next one. For example this state is the in-memory list of values for the in-memory interpreter. In the case of the lister, the state is the current line in the listing and the collection of listing lines accumulated so far.

Here is an example of the implementation for the push function:

    let private push (SLister (ln, _, _) as s) v =

        (ln, "psh", v |> sprintf "%A")
        |> SLstrLn
        |> lstappnd s,

        () |> Ok

2. Queue

2.1 The Free Monad

The library exposes a free monad for queue operations. The queue monad comes with 3 instructions:

  1. enqueue instruction which enqueues a value at the end of the queue.
  2. dequeue instruction which extracts the value from the begining of the queue.
  3. peek instruction which returns the value from the begining of the queue without remove it from the queue.

The instructions use the error type provided in Simplee.Common package in order to return the evantual failures.

1.2 Computation Builder

This monad is wrapped within queue, a computation expression builder.

The user can construct flows into an imperative way using this builder.

    let flow = queue {
        let! _ = queenq 10
        let! _ = quepeek ()
        let! r = quedeq ()
        return r
        }

3. Reader Monad

The library exposes a Reader monad, which is a function that reads from a given environment and returns a value.

type Reader<'e, 'a> = Reader of ('e -> 'a)

The main functions related to the Reader monad are rdrrun which executes a reader and/or a reader flow, rdrbind which binds a reader to a function, rdr which is the computation expression builder. You can use the built-in computation expression builder as well, for imperative programming:

    let readRun         = Reader (fun _ -> false)
    let readCfgLocal    = Reader (fun _ -> "local configuration")
    let readCfgRemote   = Reader (fun _ -> "remote configuration")

    let flow = reader {
        let! b = readRun

        match b with
        | true -> return! readCfgLocal
        | _    -> return! readCfgRemote
    }

    let res = () |> rdrrun flow
    Assert.Equal("remote configuration", res)

3. State Monad

The library exposes a State monad, which is a function that transition from a given state to another state while generating also a value at the end of the transition.

type State<'a, 's> = State of ('s -> 'a * 's)

The main functions related to the State monad are sttrun which executes a state transition and/or a state flow, sttbind which binds a state to a function, state which is the computation expression builder. You can use the built-in computation expression builder as well, for imperative programming:

    let t0 = State (fun n -> (n,   n+1))
    let t1 = State (fun n -> (n+1, n+1))

    let flow = state {
        let! r = t0            
            
        match r % 2 with
        | 0 -> return! t0
        | _ -> return! t1
    }

    let res = 1 |> sttrun flow |> fst
    Assert.Equal(3, res)

4. Writer Monad

The library exposes a Writer monad, which is a function which does not take any arguments and returns the new accumulated log and a value.

type Writer<'a, 'l> = Writer of (unit -> 'a * 'l)

The main functions related to the Writer monad are wrtrun which executes a writer transition and/or a state flow, wrtbind which binds a writer to a function, wrt which is the computation expression builder. There are several convenience functions such wrttell which adds a new log entry without returning any value, wrtpass which can apply a function returned in the result to the log entries.

The writer implementations must expose two static function: Unit and Combine.

You can use the built-in computation expression builder as well, for imperative programming:

    type LogWriter<'TLog> =
        | Log of list<'TLog>

        /// Returns the empty list
        static member Unit = [] |> Log

        /// Combines two logs
        static member Combine (Log a, Log b) = b |> List.append a |> Log

    let logs (Log lst) = lst

    let logmsg m = [m] |> Log |> wrttell 

    let flow = wrt {
        do! logmsg "Begin processing files"
        do! logmsg "Ended processing files"
    }

    let ls = flow |> wrtrun |> snd |> logs
    Assert.Equal(2, ls |> List.length)


Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 is compatible.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Added the writer monad.