Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's the approach I use to simulate Typeclasses (from <a href="http://code.google.com/p/fsharp-typeclasses/" rel="nofollow noreferrer">http://code.google.com/p/fsharp-typeclasses/</a> ). </p> <p>In your case, for Arrows could be something like this:</p> <pre class="lang-ml prettyprint-override"><code>let inline i2 (a:^a,b:^b ) = ((^a or ^b ) : (static member instance: ^a* ^b -&gt; _) (a,b )) let inline i3 (a:^a,b:^b,c:^c) = ((^a or ^b or ^c) : (static member instance: ^a* ^b* ^c -&gt; _) (a,b,c)) type T = T with static member inline instance (a:'a ) = fun x -&gt; i2(a , Unchecked.defaultof&lt;'r&gt;) x :'r static member inline instance (a:'a, b:'b) = fun x -&gt; i3(a, b, Unchecked.defaultof&lt;'r&gt;) x :'r type Return = Return with static member instance (_Monad:Return, _:option&lt;'a&gt;) = fun x -&gt; Some x static member instance (_Monad:Return, _:list&lt;'a&gt; ) = fun x -&gt; [x] static member instance (_Monad:Return, _: 'r -&gt; 'a ) = fun x _ -&gt; x let inline return' x = T.instance Return x type Bind = Bind with static member instance (_Monad:Bind, x:option&lt;_&gt;, _:option&lt;'b&gt;) = fun f -&gt; Option.bind f x static member instance (_Monad:Bind, x:list&lt;_&gt; , _:list&lt;'b&gt; ) = fun f -&gt; List.collect f x static member instance (_Monad:Bind, f:'r-&gt;'a, _:'r-&gt;'b) = fun k r -&gt; k (f r) r let inline (&gt;&gt;=) x (f:_-&gt;'R) : 'R = T.instance (Bind, x) f let inline (&gt;=&gt;) f g x = f x &gt;&gt;= g type Kleisli&lt;'a, 'm&gt; = Kleisli of ('a -&gt; 'm) let runKleisli (Kleisli f) = f type Id = Id with static member instance (_Category:Id, _: 'r -&gt; 'r ) = fun () -&gt; id static member inline instance (_Category:Id, _:Kleisli&lt;'a,'b&gt;) = fun () -&gt; Kleisli return' let inline id'() = T.instance Id () type Comp = Comp with static member instance (_Category:Comp, f, _) = (&lt;&lt;) f static member inline instance (_Category:Comp, Kleisli f, _) = fun (Kleisli g) -&gt; Kleisli (g &gt;=&gt; f) let inline (&lt;&lt;&lt;) f g = T.instance (Comp, f) g let inline (&gt;&gt;&gt;) g f = T.instance (Comp, f) g type Arr = Arr with static member instance (_Arrow:Arr, _: _ -&gt; _) = fun (f:_-&gt;_) -&gt; f static member inline instance (_Arrow:Arr, _:Kleisli&lt;_,_&gt;) = fun f -&gt; Kleisli (return' &lt;&lt;&lt; f) let inline arr f = T.instance Arr f type First = First with static member instance (_Arrow:First, f, _: 'a -&gt; 'b) = fun () (x,y) -&gt; (f x, y) static member inline instance (_Arrow:First, Kleisli f, _:Kleisli&lt;_,_&gt;) = fun () -&gt; Kleisli (fun (b,d) -&gt; f b &gt;&gt;= fun c -&gt; return' (c,d)) let inline first f = T.instance (First, f) () let inline second f = let swap (x,y) = (y,x) in arr swap &gt;&gt;&gt; first f &gt;&gt;&gt; arr swap let inline ( *** ) f g = first f &gt;&gt;&gt; second g let inline ( &amp;&amp;&amp; ) f g = arr (fun b -&gt; (b,b)) &gt;&gt;&gt; f *** g </code></pre> <p>Usage:</p> <pre class="lang-ml prettyprint-override"><code>&gt; let f = Kleisli (fun y -&gt; [y;y*2;y*3]) &lt;&lt;&lt; Kleisli ( fun x -&gt; [ x + 3 ; x * 2 ] ) ;; val f : Kleisli&lt;int,int list&gt; = Kleisli &lt;fun:f@4-14&gt; &gt; runKleisli f &lt;| 5 ;; val it : int list = [8; 16; 24; 10; 20; 30] &gt; (arr (fun y -&gt; [y;y*2;y*3])) 3 ;; val it : int list = [3; 6; 9] &gt; let (x:option&lt;_&gt;) = runKleisli (arr (fun y -&gt; [y;y*2;y*3])) 2 ;; val x : int list option = Some [2; 4; 6] &gt; ( (*) 100) *** ((+) 9) &lt;| (5,10) ;; val it : int * int = (500, 19) &gt; ( (*) 100) &amp;&amp;&amp; ((+) 9) &lt;| 5 ;; val it : int * int = (500, 14) &gt; let x:List&lt;_&gt; = (runKleisli (id'())) 5 ;; val x : List&lt;int&gt; = [5] </code></pre> <p>Note: use <code>id'()</code> instead of <code>id</code></p> <p><strong>Update:</strong> you need F# 3.0 to compile this code, otherwise <a href="http://code.google.com/p/fsharp-typeclasses/source/browse/Arrow.fs?r=a6389b6ea46ee96103d46bc71c1d7939f4aa9ff2" rel="nofollow noreferrer">here's the F# 2.0 version</a>.</p> <p>And <a href="http://nut-cracker.azurewebsites.net/typeclasses-for-fsharp/" rel="nofollow noreferrer">here's</a> a detailed explanation of this technique which is type-safe, extensible and as you can see works even with some Higher Kind Typeclasses.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload