3 Replies - 1555 Views - Last Post: 24 August 2015 - 08:07 AM

#1 g4143  Icon User is offline

  • D.I.C Head

Reputation: 17
  • View blog
  • Posts: 52
  • Joined: 30-April 09

Monads - what I have learned for simple implementation.

Posted 24 August 2015 - 02:38 AM

This is the 'short' conclusion of my investigation into the understanding of monads without Haskell or category theory.

I choose C# to investigate this concept because types are mostly in the open and well described.

From Google. A Monad is..

Quote

In functional programming, a monad is a structure that represents computations defined as sequences of steps: a type with a monad structure defines what it means to chain operations, or nest functions of that type together.


Clear as mud right?

Spoiler alert....Monads are good. They really are and they are pretty simple once you tear them apart and investigate what's really going on. And here's what's going on....

IMonad.cs
using System;

namespace IMonadProgram
{
  public interface IMonad<T>
  {
    IMonad<V> Bind<V> (Func<T, IMonad<V>> f);
  }
}



If you can understand this interface then you understand the mechanics of monads. Its really that simple. Any class that implements IMonad<T> will have a function Bind which accepts a function(Func<T, IMonad<V>> f) that returns another IMonad. Essentially Bind's only purpose is to allow the users to define how you are going to pass the current object's data to the resultant IMonad and because the function's result is a IMonad, you can repeat the process again.

Basically you can have a object MA which is a IMonad and you can create a object from the data of MA to produce object MB(object MB is a Imonad too).

var ans = MA.Bind(user_defined_function_to_pass_data_from_MA_to_MB).Bind(user_defined_function_to_pass_data_from_MB_to_MC);
//ans is a MC IMonad object



You are basically setting up IMonad pipeline which users defined the glue or Bind functions(Func<T, IMonad<V>> f) which describe how one Monad object's data is passed to the other Monad object. If you have ever used LINQ then you should see a direct parallel because LINQ was created from Monads.

The rest of a monad program in C#.

Option.cs
using System;

namespace IMonadProgram
{
  public abstract class Option<T>:IMonad<Option<T>>
  {
    public abstract bool IsNone();
    public abstract T GetValue();
    public abstract IMonad<V> Bind<V> (Func<Option<T>, IMonad<V>> f);
  }
}



None.cs
using System;

namespace IMonadProgram
{
  public class None<T>:Option<T>
  {
    public static readonly None<T> instance = new None<T>();
    private None () {}

    public override bool IsNone ()
    {
      return true;
    }
    public override T GetValue ()
    {
      throw new NotImplementedException ("None: No value to get!");
    }
    public override IMonad<V> Bind<V> (Func<Option<T>, IMonad<V>> f)
    {
      return f(this);
    }

    public override string ToString ()
    {
      return "None";
    }
  }
}



Some.cs
using System;

namespace IMonadProgram
{
  public class Some<T>:Option<T>
  {
    private T value;
    public Some (T value)
    {
      this.value = value;
    }
    public override bool IsNone ()
    {
      return false;
    }
    public override T GetValue ()
    {
      return value;
    }
    public override IMonad<V> Bind<V> (Func<Option<T>, IMonad<V>> f)
    {
      return f(this);
    }

    public override string ToString ()
    {
      return "Some: " + value.ToString();
    }
  }
}



Program.cs
using System;

namespace IMonadProgram
{
  class MainClass
  {
    public static void Main (string[] args)
    {
      Console.WriteLine (new Some<int> (400).Bind (Half));
      Console.WriteLine (new Some<int> (400).Bind (Half).Bind(Quarter));
      Console.WriteLine (new Some<int> (400).Bind (Half).Bind(Quarter).Bind(Half));
      Console.WriteLine (new Some<int> (400).Bind (Half).Bind(Quarter).Bind(Half).Bind(Quarter));
    }

    public static IMonad<Option<int>> Half(Option<int> o)
    {
      if (!o.IsNone ()) {
        if (o.GetValue () % 2 == 0) {
          return new Some<int> (o.GetValue () / 2);
        }
      }
      return None<int>.instance;
    }

    public static IMonad<Option<int>> Quarter(Option<int> o)
    {
      if (!o.IsNone ()) {
        if (o.GetValue () % 4 == 0) {
          return new Some<int> (o.GetValue () / 4);
        }
      }
      return None<int>.instance;
    }
  }
}



Console output
Some: 200
Some: 50
Some: 25
None



This is a simple example but it should demonstrate the possibilities of monads and the flexibility that's allowed because the Bind function accepts a user defined function to marshal the transfer of data.

Monads are an interesting topic that I recommend to any curious programmer.

This post has been edited by modi123_1: 24 August 2015 - 07:05 AM
Reason for edit:: Fixed the title to be more descriptive.


Is This A Good Question/Topic? 1
  • +

Replies To: Monads - what I have learned for simple implementation.

#2 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 5824
  • View blog
  • Posts: 19,835
  • Joined: 05-May 12

Re: Monads - what I have learned for simple implementation.

Posted 24 August 2015 - 06:44 AM

Is there a question, or was this meant to be contributed as a tutorial?
Was This Post Helpful? 0
  • +
  • -

#3 g4143  Icon User is offline

  • D.I.C Head

Reputation: 17
  • View blog
  • Posts: 52
  • Joined: 30-April 09

Re: Monads - what I have learned for simple implementation.

Posted 24 August 2015 - 06:50 AM

View PostSkydiver, on 24 August 2015 - 07:44 AM, said:

Is there a question, or was this meant to be contributed as a tutorial?

Its a post to show how easy it is to implement a simple monad type in C#.
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 5824
  • View blog
  • Posts: 19,835
  • Joined: 05-May 12

Re: Monads - what I have learned for simple implementation.

Posted 24 August 2015 - 08:07 AM

Moving this into the C# Discussion forum unless people feel that it should be promoted as a Tutorial.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1