Advertisement
Guest User

Untitled

a guest
Aug 4th, 2015
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.51 KB | None | 0 0
  1. using System.Reactive.Subjects;
  2. using System.Reactive.Linq;
  3. using System;
  4. using LanguageExt;
  5. using static LanguageExt.Prelude;
  6. using static Shock.Strategies;
  7. using System.Collections.Generic;
  8. using static Shock.BusinessLogic;
  9. using System.Linq;
  10. using System.Reactive.Disposables;
  11. using System.Linq.Expressions;
  12. using System.Collections;
  13.  
  14. namespace Shock
  15. {
  16. #region Variable
  17. public sealed class Variable<T> : ISubject<T>, IDisposable
  18. {
  19. private Subject<T> _subject;
  20. private Action _onDispose;
  21. private Option<T> _optional;
  22.  
  23. public Variable(Variable<T> other)
  24. {
  25. _subject = other._subject;
  26. _onDispose = other._onDispose;
  27. _optional = other._optional;
  28. }
  29.  
  30. private Variable(Subject<T> subject)
  31. {
  32. _subject = subject;
  33.  
  34. this.Subscribe(v => _optional = v);
  35. }
  36.  
  37. public static Variable<T> make(Subject<T> subject) => new Variable<T>(subject);
  38. public IDisposable Subscribe(IObserver<T> observer) => _subject.Subscribe(observer);
  39. public static Variable<T> make(Action onDispose) => make(default(T), onDispose);
  40. public void OnError(Exception error) => _subject.OnError(error);
  41. public void OnCompleted() => _subject.OnCompleted();
  42. public void OnNext(T value) => _subject.OnNext(value);
  43.  
  44. public static Variable<T> make(T value, Action onDispose) =>
  45. new Variable<T>(new Subject<T>())
  46. {
  47. _onDispose = onDispose
  48. };
  49.  
  50. private void Dispose(bool disposing)
  51. {
  52. if (disposing)
  53. {
  54. if (_onDispose != null)
  55. _onDispose();
  56.  
  57. _subject.Dispose();
  58. }
  59. }
  60.  
  61. public void Dispose()
  62. {
  63. Dispose(true);
  64. }
  65.  
  66. public T Value { get { return _optional.IfNone(null); } set { _subject.OnNext(value); } }
  67. }
  68. #endregion
  69.  
  70. #region Combinder
  71. public static class Combiner
  72. {
  73. public static IObservable<Tuple<T1, T2>> and<T1, T2, T3>
  74. ( this IObservable<T1> o1
  75. , Tuple<Func<IObservable<T1>, IObservable<T2>, IObservable<Tuple<T1, T2>>>, Func<IObservable<Tuple<T1, T2>>, IObservable<T3>, IObservable<Tuple<T1, T2, T3>>>> fun
  76. , IObservable<T2> o2
  77. ) => fun.Item1(o1, o2);
  78.  
  79. public static IObservable<Tuple<T1, T2, T3>> and<T1, T2, T3>
  80. ( this IObservable<Tuple <T1, T2>> o1
  81. , Tuple<Func<IObservable<T1>, IObservable<T2>, IObservable<Tuple<T1, T2>>>, Func<IObservable<Tuple<T1, T2>>, IObservable<T3>, IObservable<Tuple<T1, T2, T3>>>> fun
  82. , IObservable<T3> o2
  83. ) => fun.Item2(o1, o2);
  84.  
  85. public static IObservable<T3> then<T1, T2, T3>(this IObservable<Tuple<T1, T2>> o, Func<Tuple<T1, T2>, T3> fun) =>
  86. o.Select(v => { return fun(v); });
  87.  
  88. public static IObservable<T4> then<T1, T2, T3, T4>(this IObservable<Tuple<T1, T2, T3>> o, Func<Tuple<T1, T2, T3>, T4> fun) =>
  89. o.Select(v => { return fun(v); });
  90.  
  91. public static IObservable<T3> then<T1, T2, T3>(this IObservable<Tuple<T1, T2>> o, Func<T1, T2, T3> fun) =>
  92. o.then(tuplize(fun));
  93.  
  94. public static IObservable<T4> then<T1, T2, T3, T4>(this IObservable<Tuple<T1, T2, T3>> o, Func<T1, T2, T3, T4> fun) =>
  95. o.then(tuplize(fun));
  96.  
  97. public static IDisposable assign<T>(this IObservable<T> o, ISubject<T> b) => o.Subscribe(b.OnNext);
  98.  
  99. public static IDisposable assign<T>(this IObservable<T> o, Environment<T> env, string key) => o.Subscribe(env.GetOrCreate(key));
  100.  
  101. public static Func<Tuple<T1, T2>, T3> tuplize<T1, T2, T3>(Func<T1, T2, T3> fun) =>
  102. t => fun(t.Item1, t.Item2);
  103.  
  104. public static Func<Tuple<T1, T2, T3>, T4> tuplize<T1, T2, T3, T4>(Func<T1, T2, T3, T4> fun) =>
  105. t => fun(t.Item1, t.Item2, t.Item3);
  106.  
  107. public static IDisposable then<T>(this Variable<T> v, Action<T> a) => v.Subscribe(a);
  108. }
  109. #endregion
  110.  
  111. #region Consuming
  112. public class Consuming<T1, T2> : IObservable<Tuple<T1, T2>>, IDisposable
  113. {
  114. readonly IObservable<T1> _observer1;
  115. readonly IObservable<T2> _observer2;
  116.  
  117. Option<T1> _optional1;
  118. Option<T2> _optional2;
  119.  
  120. readonly IDisposable _subscription1;
  121. readonly IDisposable _subscription2;
  122.  
  123. readonly Subject<Tuple<T1, T2>> _subject = new Subject<Tuple<T1, T2>>();
  124.  
  125. public IObservable<T1> Observer1 => _observer1;
  126. public IObservable<T2> Observer2 => _observer2;
  127.  
  128. void OnT1(T1 value) =>
  129. match
  130. ( _optional2
  131. , Some: v =>
  132. {
  133. _optional2 = Option<T2>.None;
  134. _subject.OnNext(tuple(value, v));
  135. }
  136. , None: () => _optional1 = value
  137. );
  138.  
  139. void OnT2(T2 value) =>
  140. match
  141. ( _optional1
  142. , Some: v =>
  143. {
  144. _optional1 = Option<T1>.None;
  145. _subject.OnNext(tuple(v, value));
  146. }
  147. , None: () => _optional2 = value
  148. );
  149.  
  150. void OnCompleted() => _subject.OnCompleted();
  151.  
  152. void OnError(Exception error) => _subject.OnError(error);
  153.  
  154. public IDisposable Subscribe(IObserver<Tuple<T1, T2>> observer) => _subject.Subscribe(observer);
  155.  
  156. public Consuming(IObservable<T1> o1, IObservable<T2> o2)
  157. {
  158. _observer1 = o1;
  159. _observer2 = o2;
  160.  
  161. _subscription1 = _observer1.Subscribe(OnT1, OnError, OnCompleted);
  162. _subscription2 = _observer2.Subscribe(OnT2, OnError, OnCompleted);
  163. }
  164.  
  165. public void Dispose()
  166. {
  167. _subscription1.Dispose();
  168. _subscription2.Dispose();
  169. _subject.Dispose();
  170. }
  171. }
  172.  
  173. public class Consuming<T1, T2, T3> : IObservable<Tuple<T1, T2, T3>>, IDisposable
  174. {
  175. readonly IObservable<Tuple<T1, T2>> _observer1;
  176. readonly IObservable<T3> _observer2;
  177.  
  178. readonly CompositeDisposable _subscriptions;
  179. readonly Subject<Tuple<T1, T2, T3>> _subject = new Subject<Tuple<T1, T2, T3>>();
  180.  
  181. Option<Tuple<T1, T2>> _optional1;
  182. Option<T3> _optional2;
  183.  
  184. void OnT1xT2(Tuple<T1, T2> value) =>
  185. match
  186. ( _optional2
  187. , Some: v =>
  188. {
  189. _optional2 = Option<T3>.None;
  190. _subject.OnNext(tuple(value.Item1, value.Item2, v));
  191. }
  192. , None: () => _optional1 = value
  193. );
  194.  
  195. void OnT2(T3 value) =>
  196. match
  197. ( _optional1
  198. , Some: v =>
  199. {
  200. _optional1 = Option<Tuple<T1, T2>>.None;
  201. _subject.OnNext(tuple(v.Item1, v.Item2, value));
  202. }
  203. , None: () => _optional2 = value
  204. );
  205.  
  206. void OnCompleted() => _subject.OnCompleted();
  207.  
  208. void OnError(Exception error) => _subject.OnError(error);
  209.  
  210. public IDisposable Subscribe(IObserver<Tuple<T1, T2, T3>> observer) => _subject.Subscribe(observer);
  211.  
  212. public Consuming(IObservable<Tuple<T1, T2>> o1, IObservable<T3> o2)
  213. {
  214.  
  215. _observer1 = o1;
  216. _observer2 = o2;
  217.  
  218. _subscriptions = new CompositeDisposable
  219. ( _observer1.Subscribe(OnT1xT2, OnError, OnCompleted)
  220. , _observer2.Subscribe(OnT2, OnError, OnCompleted)
  221. );
  222. }
  223.  
  224. public void Dispose()
  225. {
  226. _subscriptions.Dispose();
  227. _subject.Dispose();
  228. }
  229. }
  230. #endregion
  231.  
  232. #region Strategies
  233. public static class Strategies
  234. {
  235. public static Tuple<Func<IObservable<T1>, IObservable<T2>, IObservable<Tuple<T1, T2>>>, Func<IObservable<Tuple<T1, T2>>, IObservable<T3>, IObservable<Tuple<T1, T2, T3>>>> _buffer<T1, T2, T3>() =>
  236. Tuple.Create<Func<IObservable<T1>, IObservable<T2>, IObservable<Tuple<T1, T2>>>, Func<IObservable<Tuple<T1, T2>>, IObservable<T3>, IObservable<Tuple<T1, T2, T3>>>>
  237. ( (o1, o2) => o1.CombineLatest(o2, (v1, v2) => tuple(v1, v2))
  238. , (o1, o2) => o1.CombineLatest(o2, (t, v) => tuple(t.Item1, t.Item2, v))
  239. );
  240.  
  241. public static Tuple<Func<IObservable<T1>, IObservable<T2>, IObservable<Tuple<T1, T2>>>, Func<IObservable<Tuple<T1, T2>>, IObservable<T3>, IObservable<Tuple<T1, T2, T3>>>> _consume<T1, T2, T3>() =>
  242. Tuple.Create<Func<IObservable<T1>, IObservable<T2>, IObservable<Tuple<T1, T2>>>, Func<IObservable<Tuple<T1, T2>>, IObservable<T3>, IObservable<Tuple<T1, T2, T3>>>>
  243. ( (o1, o2) => new Consuming<T1, T2>(o1, o2)
  244. , (o1, o2) => new Consuming<T1, T2, T3>(o1, o2)
  245. );
  246.  
  247. }
  248. #endregion
  249.  
  250. #region StandardStrategiess
  251. public static class StandardStrategies
  252. {
  253. public static Tuple<Func<IObservable<int>, IObservable<int>, IObservable<Tuple<int, int>>>, Func<IObservable<Tuple<int, int>>, IObservable<int>, IObservable<Tuple<int, int, int>>>> ConsumeInt => _consume<int, int, int>();
  254. public static Tuple<Func<IObservable<float>, IObservable<float>, IObservable<Tuple<float, float>>>, Func<IObservable<Tuple<float, float>>, IObservable<float>, IObservable<Tuple<float, float, float>>>> ConsumeFloat => _consume<float, float, float>();
  255. public static Tuple<Func<IObservable<int>, IObservable<int>, IObservable<Tuple<int, int>>>, Func<IObservable<Tuple<int, int>>, IObservable<int>, IObservable<Tuple<int, int, int>>>> BufferInt => _buffer<int, int, int>();
  256. public static Tuple<Func<IObservable<float>, IObservable<float>, IObservable<Tuple<float, float>>>, Func<IObservable<Tuple<float, float>>, IObservable<float>, IObservable<Tuple<float, float, float>>>> BufferFloat => _buffer<float, float, float>();
  257. }
  258. #endregion
  259.  
  260. #region FunctionOf
  261. public static class Function
  262. {
  263. public static IObservable<T3> Of<T1, T2, T3, T4>
  264. ( Expression<Func<T1, T2, T3>> expr
  265. , IDictionary<string, Variable<T1>> env1
  266. , IDictionary<string, Variable<T2>> env2
  267. , Tuple
  268. < Func<IObservable<T1>, IObservable<T2>, IObservable<Tuple<T1, T2>>>
  269. , Func<IObservable<Tuple<T1, T2>>, IObservable<T4>, IObservable<Tuple<T1, T2, T4>>>
  270. > fun
  271. )
  272. {
  273. var parameterNames = expr.Parameters.Select(p => p.Name).ToArray();
  274. var consume = _consume<T1, T2, T3>();
  275.  
  276. if (expr.Body is MethodCallExpression)
  277. {
  278. var function = (MethodCallExpression)expr.Body;
  279. var method = function.Method;
  280. var arguments = function.Arguments.Cast<ParameterExpression>().Select(p => p.Name).ToArray();
  281. var x = env1[arguments[0]];
  282. var y = env2[arguments[1]];
  283.  
  284. return x.and(fun, y).then(t => (T3)method.Invoke(null, new[] { (object)t.Item1, t.Item2 }));
  285. }
  286.  
  287. throw new Exception("unsuported expression.");
  288. }
  289.  
  290. public static IObservable<T4> Of<T1, T2, T3, T4>
  291. ( Expression<Func<T1, T2, T3, T4>> expr
  292. , IDictionary<string, Variable<T1>> env1
  293. , IDictionary<string, Variable<T2>> env2
  294. , IDictionary<string, Variable<T3>> env3
  295. , Tuple
  296. < Func<IObservable<T1>, IObservable<T2>, IObservable<Tuple<T1, T2>>>
  297. , Func<IObservable<Tuple<T1, T2>>, IObservable<T3>, IObservable<Tuple<T1, T2, T3>>>
  298. > fun
  299. )
  300. {
  301. var parameterNames = expr.Parameters.Select(p => p.Name).ToArray();
  302. var consume = _consume<T1, T2, T3>();
  303. var body = expr.Body;
  304.  
  305. if (expr.Body is MethodCallExpression)
  306. {
  307. var function = (expr.Body as MethodCallExpression);
  308. var method = (expr.Body as MethodCallExpression).Method;
  309. var arguments = function.Arguments.Cast<ParameterExpression>().Select(p => p.Name).ToArray();
  310. var x = env1[arguments[0]];
  311. var y = env2[arguments[1]];
  312. var z = env3[arguments[2]];
  313.  
  314. return x.and(fun, y).and(fun, z).then(t => (T4)method.Invoke(null, new[] { (object)t.Item1, t.Item2, t.Item3 }));
  315. }
  316. //TODO conversions
  317. //else if (expr.Body is UnaryExpression && (expr.Body as UnaryExpression).NodeType == ExpressionType.Convert)
  318. //{
  319. // var function = (expr.Body as UnaryExpression);
  320. // var operand = (MethodCallExpression)function.Operand;
  321.  
  322. // return FunctionOf(expr.Body, env1, env2, retVariable, fun);
  323.  
  324. // var method = (expr.Body as MethodCallExpression).Method;
  325.  
  326. // return null;
  327. //}
  328.  
  329. throw new Exception("unsuported expression.");
  330. }
  331. }
  332. #endregion
  333.  
  334. #region Environment
  335. public class Environment<T> : IDisposable, IDictionary<string, Variable<T>>
  336. {
  337. private readonly Dictionary<string, Variable<T>> _dictionaryVariables = new Dictionary<string, Variable<T>>();
  338. private readonly Dictionary<string, T> _dictionary = new Dictionary<string, T>();
  339.  
  340. public ICollection<string> Keys => _dictionaryVariables.Keys;
  341. public ICollection<Variable<T>> Values => _dictionaryVariables.Values;
  342. public int Count => _dictionaryVariables.Count;
  343. public bool IsReadOnly => true;
  344.  
  345. Variable<T> IDictionary<string, Variable<T>>.this[string key]
  346. {
  347. get { return GetOrCreate(key); }
  348. set { throw new Exception(); }
  349. }
  350.  
  351. public Variable<T> this[string key] => GetOrCreate(key);
  352.  
  353. public Environment(Dictionary<string, T> dictionary)
  354. {
  355. _dictionary = dictionary;
  356. }
  357.  
  358. public Variable<T> GetOrCreate(string key) => GetOrCreate(key, default(T));
  359.  
  360. public Variable<T> GetOrCreate(string key, T value)
  361. {
  362. if (_dictionaryVariables.ContainsKey(key) == false)
  363. {
  364. _dictionaryVariables[key] = Variable<T>.make
  365. ( value
  366. , () =>
  367. {
  368. if (_dictionary.ContainsKey(key))
  369. _dictionary.Remove(key);
  370.  
  371. if (_dictionaryVariables.ContainsKey(key))
  372. _dictionaryVariables.Remove(key);
  373. }
  374. );
  375.  
  376. _dictionaryVariables[key].Subscribe(v => _dictionary[key] = v);
  377. }
  378.  
  379. var result = _dictionaryVariables[key];
  380.  
  381. return result;
  382. }
  383.  
  384. private void Dispose(bool disposing)
  385. {
  386. if (disposing)
  387. {
  388. var list = new List<Variable<T>>();
  389.  
  390. foreach (var k in _dictionaryVariables)
  391. list.Add(k.Value);
  392.  
  393. list.ForEach(v => v.Dispose());
  394. }
  395. }
  396.  
  397. public void Dispose()
  398. {
  399. Dispose(true);
  400. GC.SuppressFinalize(this);
  401. }
  402.  
  403. public bool ContainsKey(string key)
  404. {
  405. throw new NotImplementedException();
  406. }
  407.  
  408. public void Add(string key, Variable<T> value)
  409. {
  410. throw new NotImplementedException();
  411. }
  412.  
  413. public bool Remove(string key)
  414. {
  415. throw new NotImplementedException();
  416. }
  417.  
  418. public bool TryGetValue(string key, out Variable<T> value)
  419. {
  420. throw new NotImplementedException();
  421. }
  422.  
  423. public void Add(KeyValuePair<string, Variable<T>> item)
  424. {
  425. throw new NotImplementedException();
  426. }
  427.  
  428. public void Clear()
  429. {
  430. throw new NotImplementedException();
  431. }
  432.  
  433. public bool Contains(KeyValuePair<string, Variable<T>> item)
  434. {
  435. throw new NotImplementedException();
  436. }
  437.  
  438. public void CopyTo(KeyValuePair<string, Variable<T>>[] array, int arrayIndex)
  439. {
  440. throw new NotImplementedException();
  441. }
  442.  
  443. public bool Remove(KeyValuePair<string, Variable<T>> item)
  444. {
  445. throw new NotImplementedException();
  446. }
  447.  
  448. public IEnumerator<KeyValuePair<string, Variable<T>>> GetEnumerator()
  449. {
  450. throw new NotImplementedException();
  451. }
  452.  
  453. IEnumerator IEnumerable.GetEnumerator()
  454. {
  455. throw new NotImplementedException();
  456. }
  457. }
  458. #endregion
  459.  
  460. #region BusinessLogic
  461. public static class BusinessLogic
  462. {
  463. public static float Multiply(float x, float y) => x * y;
  464. public static float Add3(int x, int y, int z) => x + y + z;
  465. }
  466. #endregion
  467.  
  468. class Program
  469. {
  470. [STAThread]
  471. public static void Main(string[] args)
  472. {
  473. #region databases
  474. var database1 = new Dictionary<string, int>();
  475.  
  476. database1.Add("x", 0);
  477. database1.Add("y", 0);
  478. database1.Add("z", 0);
  479.  
  480. var database2 = new Dictionary<string, float>();
  481.  
  482. database2.Add("v", 0);
  483. database2.Add("sum", 0);
  484. database2.Add("endValue", 0);
  485. #endregion
  486.  
  487. var strategyFloat = StandardStrategies.BufferFloat;
  488. var strategyInt = StandardStrategies.BufferInt;
  489. //var strategyFloat = StandardStrategies.ConsumeFloat;
  490. //var strategyInt = StandardStrategies.ConsumeInt;
  491.  
  492. using (var env1 = new Environment<int>(database1))
  493. using (var env2 = new Environment<float>(database2))
  494. using (Function.Of(expr((int x, int y, int z) => Add3(x, y, z)), env1, env1, env1, strategyInt).assign(env2, "sum"))
  495. using (Function.Of(expr((float sum, float v) => Multiply(sum, v)), env2, env2, strategyFloat).assign(env2, "endValue"))
  496. {
  497. #region variables
  498. var x = env1["x"];
  499. var y = env1["y"];
  500. var z = env1["z"];
  501.  
  502. var v = env2["v"];
  503. var endValue = env2["endValue"];
  504. #endregion
  505.  
  506. endValue.then(Console.WriteLine);
  507.  
  508. x.Value = 1;
  509. y.Value = 2;
  510. z.Value = 3;
  511. v.Value = 3.14f;
  512. v.Value = 2.9f;
  513. //z.Value = 5;
  514. //v.Value = 6;
  515.  
  516. Console.WriteLine("Read from database");
  517. Console.WriteLine(database2["endValue"]);
  518. }
  519.  
  520. System.Console.ReadKey();
  521. }
  522. }
  523. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement