Advertisement
sglienke

Maybe monad

Jan 20th, 2015
222
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. program MaybeMonad;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. {$I Spring.inc}
  6.  
  7. uses
  8.   Spring,
  9.   Spring.Collections,
  10.   SysUtils,
  11.   TypInfo;
  12.  
  13. type
  14.   Maybe<T> = record
  15.   strict private
  16.     fValues: TArray<T>;
  17.   public
  18.     constructor Create(const value: T);
  19.     function Get: IEnumerable<T>;
  20.     function GetEnumerator: IEnumerator<T>;
  21.  
  22.     class operator Implicit(const value: Maybe<T>): IEnumerable<T>;
  23.     class operator Implicit(const value: T): Maybe<T>;
  24.   end;
  25.  
  26. constructor Maybe<T>.Create(const value: T);
  27. begin
  28.  case {$IFDEF DELPHIXE7_UP}System.GetTypeKind(T){$ELSE}GetTypeKind(TypeInfo(T)){$ENDIF} of
  29.     tkClass, tkArray, tkInterface, tkDynArray, tkClassRef, tkPointer, tkProcedure:
  30.     if (PPointer(@value)^ = nil) then
  31.       Exit;
  32.   end;
  33.   SetLength(fValues, 1);
  34.   fValues[0] := value;
  35. end;
  36.  
  37. function Maybe<T>.Get: IEnumerable<T>;
  38. begin
  39.   Result := Self;
  40. end;
  41.  
  42. function Maybe<T>.GetEnumerator: IEnumerator<T>;
  43. begin
  44.   Result := IEnumerable<T>(Self).GetEnumerator;
  45. end;
  46.  
  47. class operator Maybe<T>.Implicit(const value: Maybe<T>): IEnumerable<T>;
  48. begin
  49.   Result := TEnumerable.Query<T>(value.fValues);
  50. end;
  51.  
  52. class operator Maybe<T>.Implicit(const value: T): Maybe<T>;
  53. begin
  54.   Result := Maybe<T>.Create(value);
  55. end;
  56.  
  57. function Divide(const x, y: Integer): Maybe<Integer>;
  58. begin
  59.   if y <> 0 then
  60.     Result := x div y;
  61. end;
  62.  
  63. function DoSomeDivision(denominator: Integer): Maybe<Integer>;
  64. var
  65.   a, b: Integer;
  66. begin
  67.   for a in Divide(42, denominator) do
  68.     for b in Divide(a, 2) do
  69.       Result := b;
  70. end;
  71.  
  72. var
  73.   a: string;
  74.   b: Integer;
  75.   c: TDateTime;
  76.   result: Maybe<string>;
  77. begin
  78.   try
  79.     for a in TArray<string>.Create('Hello World!') do
  80.       for b in DoSomeDivision(0) do
  81.         for c in TArray<TDateTime>.Create(EncodeDate(2010, 1, 14)) do
  82.           result := a + ' ' + IntToStr(b) + ' ' + DateTimeToStr(c);
  83.     Writeln(result.Get.FirstOrDefault('Nothing'));
  84.   except
  85.     on E: Exception do
  86.       Writeln(E.ClassName, ': ', E.Message);
  87.   end;
  88.   Readln;
  89. end.
Advertisement
RAW Paste Data Copied
Advertisement