Δημοσιεύτηκε στις Σάββατο, 27 Φεβρουαρίου 2010 2:06 μμ από το μέλος PALLADIN :: 0 σχόλια

Reactive Monads


Το Rx είναι το νέο δημιούργημα του Erik Meijer, και μετά από μήνες ενασχόλησης μαζί του, νομίζω ότι είναι απλά 'a work of genius'.
Αυτό που κάνει είναι να δρα ως compositional glue για events, asynchronous calls  και γενικά για push based computations.

Κατεβάστε το από εδώ και αρχίστε να εξερευνείτε τις δυνατότητές του (You will be amazed).

Ως ένα παράδειγμα της μαγείας του, έγραψα ένα κλασσικό mouse move recording and playback.

	    var mouseMoveObservable = Observable.Merge(new Control[] { this, recordButton, stopButton, playButton }
                                                    		.Select(control => Observable.FromEvent<MouseEventArgs>(control, "MouseMove")));

            ReplaySubject<TimeInterval<IEvent<MouseEventArgs>>> replayObservable = null;
            Observable.FromEvent<EventArgs>(recordButton, "Click").ObserveOnWindowsForms().Subscribe(_ =>
            {
                stopButton.Enabled = true; recordButton.Enabled = false;
                replayObservable = mouseMoveObservable.TimeInterval().Record();
                replayObservable.ObserveOnWindowsForms().Subscribe(time => this.Text = String.Format("{0},{1}", time.Value.EventArgs.X, time.Value.EventArgs.Y));
            });

            Observable.FromEvent<EventArgs>(stopButton, "Click").ObserveOnWindowsForms().Subscribe(_ =>
            {
                replayObservable.Dispose();
                stopButton.Enabled = false; playButton.Enabled = true;
            });
            
            Observable.FromEvent<EventArgs>(playButton, "Click").ObserveOnWindowsForms().Subscribe(_ =>
            {
                playButton.Enabled = false;
                var playObservable = replayObservable.ToEnumerable()
                                     .Aggregate(Observable.Return(new Unit()),
                                                (accObservable, timeMouse) => accObservable.Delay(timeMouse.Interval)
                                                                                            .ObserveOnWindowsForms()                                                                                            
                                                                                            .Do(__ => Cursor.Position = ((Control)timeMouse.Value.Sender).PointToScreen(new Point(timeMouse.Value.EventArgs.X, timeMouse.Value.EventArgs.Y))));
                playObservable.Subscribe(value => { }, () => recordButton.Enabled = true);
            });


Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr

Attachment(s): TestRx.zip
Δημοσιεύτηκε στις Κυριακή, 7 Φεβρουαρίου 2010 11:40 μμ από το μέλος PALLADIN :: 0 σχόλια

LiftM'e' up Scotty

Έχοντας αναπτύξει όλο το απαραίτητο machinery (1, 2), μπορούμε να συνεχίσουμε με την ίδια αφαιρετική διάθεση και να "ανεβάσουμε" στον κόσμο του 'M',
συναρτήσεις με ένα, δυο ή περισσότερα arguments.

// liftM declarations
let liftM<'M, 'A1, 'R when 'M :> MonadDef<'M>> (m : MonadDef<'M>) (f : 'A1 -> 'R) 
                                               (a : IMonad<'A1, 'M>) : IMonad<'R, 'M> = 
                                               m.Map(f, a)

let liftM2<'M, 'A1, 'A2, 'R when 'M :> MonadDef<'M>> (m : MonadDef<'M>) (f : 'A1 -> 'A2 -> 'R) 
                                                     (a : IMonad<'A1, 'M>) (b : IMonad<'A2, 'M>) : IMonad<'R, 'M> =
                                                     m.Apply(liftM m f a, b)

let liftM3<'M, 'A1, 'A2, 'A3, 'R when 'M :> MonadDef<'M>> (m : MonadDef<'M>) (f : 'A1 -> 'A2 -> 'A3 -> 'R) 
                                                          (a : IMonad<'A1, 'M>) (b : IMonad<'A2, 'M>) 
                                                          (c : IMonad<'A3, 'M>) : IMonad<'R, 'M> =
                                                          m.Apply(liftM2 m f a b, c)  

//liftM example
let result = liftM2 listM (+) (listM.OfList [0; 1]) (listM.OfList [0; 2])
printfn "%A" result //[0; 2; 1; 3]

Haskell inspiration
http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html

 

Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr

Attachment(s): GenericMonads.zip
Δημοσιεύτηκε στις Κυριακή, 17 Ιανουαρίου 2010 8:17 μμ από το μέλος PALLADIN :: 1 σχόλια

Abstracting over 'M' (generic functions)

(Haskell ideas => F# (OOP + FP))

Στην Haskell, επειδή έχουμε higher kind polymorphism, μπορούμε να ορίσουμε κάποιες πολύ χρήσιμες και αρκετά γενικές συναρτήσεις για Monads.
Σκέφτηκα να προσπαθήσω να κάνω κάτι αντίστοιχο σε F# (υλοποιώντας ένα Generic List Monad) και να ορίσω τις κλασσικές sequence, mapM, filterM.

Ως παράδειγμα της δύναμης που μας προσφέρει η αφαίρεση, μπορούμε να ορίσουμε την συνάρτηση του powerset ως εξής:
let powerSet xs = listM.FilterM ((fun _ -> listM.OfList [false; true]), listM.OfList xs) // it's magic

Χρησιμοποιώντας subtype polymorphism και μερικά περιορισμένα downcasts, καταφέραμε να φέρουμε λίγο από το άρωμα και την αίγλη της Haskell στον κόσμο της F#.

Happy hacking...

module MonadModule = 
    //Generic Monad Definition
    [<AbstractClass>]
    type MonadDef<'M when 'M :> MonadDef<'M>>() as this = 
         let (>>=) m f = this.Bind(m, f)
         let unit v = this.Return v
         static let listDef = ListDef()

         abstract member Return<'T> : 'T -> IMonad<'T,'M> 
         abstract member Bind<'T, 'S> : IMonad<'T,'M> * ('T -> IMonad<'S,'M>) -> IMonad<'S,'M> 
         abstract member Zero<'T> : unit -> IMonad<'T,'M>
         
         member this.Delay(f) = unit () >>= fun () -> f()
         member this.Combine<'T>(first : IMonad<unit, 'M>, second : IMonad<'T, 'M>) : IMonad<'T, 'M>  = 
            this.Then (first, second)

         member this.Then<'T, 'S>(firstM : IMonad<'T, 'M>, secondM : IMonad<'S, 'M>) : IMonad<'S, 'M> =
            firstM >>= fun _ -> secondM

         member this.Map<'T, 'S>(f : 'T -> 'S, m : IMonad<'T, 'M>) : IMonad<'S, 'M> =
            m >>= fun v -> unit (f v)

         member this.Apply<'T, 'S>(mf : IMonad<'T -> 'S, 'M>, m : IMonad<'T, 'M>) : IMonad<'S, 'M> =
            mf >>= fun f -> m >>= fun v -> unit (f v)   

         member this.Join<'T>(m : IMonad<IMonad<'T, 'M>, 'M>) : IMonad<'T, 'M> =
            m >>= id

         member this.Sequence<'T>(lm : IMonad<IMonad<'T, 'M>, ListDef>) : IMonad<IMonad<'T, ListDef>, 'M> =
            match lm :?> _ with
            | Nil -> unit (Nil :> _)
            | Cons (m, ms) -> m >>= fun v -> this.Sequence ms >>= fun vs -> unit (listDef.ConsM v vs)
        
         member this.MapM<'T, 'S>(f : 'T -> IMonad<'S, 'M>, l : IMonad<'T, ListDef>) : IMonad<IMonad<'S, ListDef>, 'M> =  
            this.Sequence (listDef.Map ((fun v -> f v), l))

         member this.FilterM<'T>(p : 'T -> IMonad<bool, 'M>, l : IMonad<'T, ListDef>) : IMonad<IMonad<'T, ListDef>, 'M> =
            match l :?> _ with
            | Nil -> unit (Nil :> _)
            | Cons (x, xs) -> p x >>= fun b -> this.FilterM (p, xs) >>= fun ys -> if b then unit (listDef.ConsM x ys) else unit ys   

    and IMonad<'T,'M when 'M :> MonadDef<'M>> = interface end 

    // List Monad
    and List<'T> = 
        | Nil
        | Cons of ('T * List<'T>)
        interface IMonad<'T, ListDef>
    and
        ListDef() = 
            inherit MonadDef<ListDef>() with
                member this.OfList<'T>(xs : list<'T>) : IMonad<'T, ListDef> =
                    List.foldBack (fun v acc -> this.ConsM v acc) xs <| this.Zero() 

                member this.ConsM (x : 'T) (acc : IMonad<'T, ListDef>) : IMonad<'T, ListDef> = Cons (x, acc :?> _) :> _
                 
                member this.Foldr<'T, 'S>(f : 'T -> 'S -> 'S, seed : 'S, list : IMonad<'T, ListDef>) : 'S =
                    match list :?> _ with
                    | Nil -> seed
                    | Cons (x, xs) -> f x (this.Foldr (f, seed, xs) )

                member this.Concat<'T>(first : IMonad<'T, ListDef>, second : IMonad<'T, ListDef>) : IMonad<'T, ListDef> =
                    this.Foldr(this.ConsM, second, first)

                override this.Return<'T>(v : 'T) : IMonad<'T, ListDef> = 
                    Cons (v, Nil) :> _ 
          
                override this.Bind<'T,'S>(m : IMonad<'T, ListDef>, f : 'T -> IMonad<'S, ListDef>) : IMonad<'S, ListDef> =  
                    this.Foldr ((fun x acc -> this.Concat (f x, acc)), Nil :> _, m)

                override this.Zero<'T>() : IMonad<'T, ListDef> = 
                    Nil :> _ 
 
    let listM = ListDef()

open MonadModule

// Maybe Monad
module MaybeModule =

    type Maybe<'T> = 
        | Nothing 
        | Just of 'T 
        interface IMonad<'T, MaybeDef> 
    and 
        
        MaybeDef() = 
            inherit MonadDef<MaybeDef>() with
                override this.Return<'T>(v : 'T) : IMonad<'T, MaybeDef> = 
                    Just v :> _ 
      
                override this.Bind<'T,'S>(m : IMonad<'T, MaybeDef>, f : 'T -> IMonad<'S, MaybeDef>) : IMonad<'S, MaybeDef> = 
                    match m :?> _ with 
                    | Nothing -> Nothing :> _ 
                    | Just x  -> f x

                override this.Zero<'T>() : IMonad<'T, MaybeDef> = 
                    Nothing :> _
                
                member this.Just<'T>(value : 'T) : IMonad<'T, MaybeDef> =
                    Just value :> _
                member this.Nothing<'T>() : IMonad<'T, MaybeDef> =
                    Nothing :> _
    
    let maybeM = new MaybeDef()     
 

open MaybeModule


//Examples

let test = listM.OfList [ maybeM.Just 1; maybeM.Just 2 ]
maybeM.Sequence test |> printfn "%A"


let powerSet xs = listM.FilterM ((fun _ -> listM.OfList [false; true]), listM.OfList xs)
powerSet [1..3] |> printfn "%A"
Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Δημοσιεύτηκε στις Κυριακή, 27 Δεκεμβρίου 2009 2:03 μμ από το μέλος PALLADIN :: 0 σχόλια

Only for language geeks

No comment

Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Δημοσιεύτηκε στις Κυριακή, 20 Δεκεμβρίου 2009 3:53 μμ από το μέλος PALLADIN :: 3 σχόλια

Abstracting over 'M' (in F#)

Μετά από αρκετές αποτυχημένες προσπάθειες, στο να συνδυάσω Type constructor polymorphism και LINQ syntax, αποφάσισα
να δοκιμάσω τις ίδιες ιδέες σε F#.

Η F# υλοποίηση είναι ακριβώς ίδια με την αντίστοιχη σε C#, με την μονη διαφορα ότι το Monad generalization δουλεύει με το ειδικό
syntax support που μας παρέχουν τα computation expressions.

[<AbstractClass>]
type MonadDef<'M when 'M :> MonadDef<'M>>() as this = 
     let (>>=) m f = this.Bind(m, f)
     let unit v = this.Return v

     abstract member Return<'T> : 'T -> IMonad<'T,'M> 
     abstract member Bind<'T, 'S> : IMonad<'T,'M> * ('T -> IMonad<'S,'M>) -> IMonad<'S,'M> 
    
     member this.Then<'T, 'S>(firstM : IMonad<'T, 'M>, secondM : IMonad<'S, 'M>) : IMonad<'S, 'M> =
        firstM >>= fun _ -> secondM

     member this.Map<'T, 'S>(f : 'T -> 'S, m : IMonad<'T, 'M>) : IMonad<'S, 'M> =
        m >>= fun v -> unit (f v)

     member this.Apply<'T, 'S>(mf : IMonad<'T -> 'S, 'M>, m : IMonad<'T, 'M>) : IMonad<'S, 'M> =
        mf >>= fun f -> m >>= fun v -> unit (f v)   

     member this.Join<'T>(m : IMonad<IMonad<'T, 'M>, 'M>) : IMonad<'T, 'M> =
        m >>= id

and IMonad<'T,'M when 'M :> MonadDef<'M>> = interface end 

type Maybe<'T> = 
    | Nothing 
    | Just of 'T 
    interface IMonad<'T, MaybeDef> 
and 
    MaybeDef() = 
        inherit MonadDef<MaybeDef>() with
            override this.Return<'T>(v : 'T) : IMonad<'T, MaybeDef> = 
                Just v :> _ 
  
            override this.Bind<'T,'S>(m : IMonad<'T, MaybeDef>, f : 'T -> IMonad<'S, MaybeDef>) : IMonad<'S,MaybeDef> = 
                match m :?> _ with 
                | Nothing -> Nothing :> _ 
                | Just x  -> f x 


let maybe = new MaybeDef() 

let toMaybeString a = 
    maybe { 
        let! v = Just a  
        return v.ToString()
    }

printfn "%A" (toMaybeString 42)
Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Δημοσιεύτηκε στις Παρασκευή, 6 Νοεμβρίου 2009 2:11 μμ από το μέλος PALLADIN :: 3 σχόλια

Διομήδης Σπινέλλης

Πριν πολλά πολλά χρονια... είχα αγοράσει ένα βιβλίο που είχε στο εξώφυλλο ένα ψάρι (the "fish book")!!!
Αυτό που βρήκα περίεργο στο βιβλίο δεν ήταν το ψάρι αλλα αυτός ο κώδικας

/* DDS-BASIC interpreter in "C" annotated by Michael Somos 1997 */
/* INPUT bug fix 07Sep2005 Somos */
/* original by Diomidis Spinellis for 1990 IOCCC
<URL:http://reality.sgi.com/csp/ioccc/1990/dds.c>

#define O(b,f,u,s,c,a)b(){int o=f();switch(*p++){X u:_ o s b();X c:_ o a b();default:p--;_ o;}}
#define t(e,d,_,C)X e:f=fopen(B+d,_);C;fclose(f)
#define U(y,z)while(p=Q(s,y))*p++=z,*p=' '
#define N for(i=0;i<11*R;i++)m[ i ]&&
#define I "%d %s\n",i,m[ i ]
#define X ;break;case
#define _ return
#define R 999
typedef char*A;int*C,E[R],L[R],M[R],P[R],l,i,j;char B[R],F[2];A m[12*R],malloc
(),p,q,x,y,z,s,d,f,fopen();A Q(s,o)A s,o;{for(x=s;*x;x++){for(y=x,z=o;*z&&*y==
*z;y++)z++;if(z>o&&!*z)_ x;}_   0;}main(){m[11*R]="E";while(puts("Ok"),gets(B)
)switch(*B){X'R':C=E;l=1;for(i=0;i<R;P[i++]=0);while(l){while(!(s=m[l]))l++;if
(!Q(s,"\"")){U("<>",'#');U("<=",'$');U(">=",'!');}d=B;while(*F=*s){*s=='"'&&j
++;if(j&1||!Q(" \t",F))*d++=*s;s++;}*d--=j=0;if(B[1]!='=')switch(*B){X'E':l=-1
X'R':B[2]!='M'&&(l=*--C)X'I':B[1]=='N'?gets(p=B),P[*d]=S():(*(q=Q(B,"TH"))=0,p
=B+2,S()&&(p=q+4,l=S()-1))X'P':B[5]=='"'?*d=0,puts(B+6):(p=B+5,printf("%d\n",S
()))X'G':p=B+4,B[2]=='S'&&(*C++=l,p++),l=S()-1 X'F':*(q=Q(B,"TO"))=0;p=B+5;P[i
=B[3]]=S();p=q+2;M[ i ]=S();L[ i ]=l X'N':++P[*d]<=M[*d]&&(l=L[*d]);}else p=B+2,P[
*B]=S();l++;}X'L':N printf(I)X'N':N free(m[ i ]),m[ i ]=0   X'B':_ 0 t('S',5,"w",N
fprintf(f,I))t('O',4,"r",while(fgets(B,R,f))(*Q(B,"\n")=0,G()))X 0:default:G()
;}_ 0;}G(){l=atoi(B);m[l]&&free(m[l]);(p=Q(B," "))?strcpy(m[l]=malloc(strlen(p
)),p+1):(m[l]=0,0);}O(S,J,'=',==,'#',!=)O(J,K,'<',<,'>',>)O(K,V,'$',<=,'!',>=)
O(V,W,'+',+,'-',-)O(W,Y,'*',*,'/',/)Y(){int o;_*p=='-'?p++,-Y():*p>='0'&&*p<=
'9'?strtol(p,&p,0):*p=='('?p++,o=S(),p++,o:P[*p++];}
Τι θέλει να πει ο ποιητής και ποιος είναι αυτός ο Διομήδης Σπινέλλης,,,μετά από κάποια χρονια έμαθα!!!
Πολλά συγχαρητήρια και από εμενα...
Πόσες χώρες έχουν έναν hacker σε τέτοια θέση!!!

Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Δημοσιεύτηκε στις Κυριακή, 25 Οκτωβρίου 2009 5:34 μμ από το μέλος PALLADIN :: 3 σχόλια

Abstracting over 'M'

Τον τελευταίο καιρό ψάχνω κάποιο φορμαλισμό (σε C#) ώστε να μπορέσω να έχω έναν generic-reusable ορισμό ενός Monad.
Αυτό που λείπει από τα .Net generics είναι η δυνατότητα να έχω abstraction σε επίπεδο Type Constructor.

Σαν παράδειγμα της συγκεκριμένης αφαίρεσης, παρουσιάζω τον generic ορισμό ενός Monad μέσα από δυο αγαπημένες μου γλώσσες.

Haskell
class Monad m where
  (>>=) :: m a -> (a -> m b) -> m b
  return :: a -> m a


Scala
class Monad[M[_]] {
	def unit[T](a: T): M[T]
	def bind[T, K](m: M[T], f: T => M[K]): M[K]
}
Μετά από αρκετό πειραματισμό και μελέτη, κατέληξα στον παρακάτω κώδικα.
	abstract class Monad<T, M> where M : MonadDef<M> { }
	abstract class MonadDef<M> where M : MonadDef<M>
	{
		public abstract Monad<T, M> Unit<T>(T value);
		public abstract Monad<S, M> Bind<T, S>(Monad<T, M> monad, Func<T, Monad<S, M>> func);

		public Monad<S, M> Then<T, S>(Monad<T, M> first, Monad<S, M> second)
		{
			return Bind(first, _ => second);
		}

		public Monad<S, M> Map<T, S>(Monad<T, M> monad, Func<T, S> f)
		{
			return Bind(monad, value => Unit(f(value)));
		}

		public Monad<T, M> Join<T>(Monad<Monad<T, M>, M> monad)
		{
			return Bind(monad, value => value);
		}
	}
	// Maybe Monad implementation 
	abstract class Maybe<T> : Monad<T, MaybeDef>
	{
	}
	sealed class Just<T> : Maybe<T>
	{
		public T Value { private set; get; }
		public Just(T value) { Value = value; }
	}
	sealed class Nothing<T> : Maybe<T> { }

	static class MaybeMonadExtensions
	{
		public static Maybe<T> ToMaybe<T>(this Monad<T, MaybeDef> monad)
		{
			return (Maybe<T>)monad;
		}
	}

	sealed class MaybeDef : MonadDef<MaybeDef>
	{

		public override Monad<T, MaybeDef> Unit<T>(T value)
		{
			return new Just<T>(value);
		}

		public override Monad<S, MaybeDef> Bind<T, S>(Monad<T, MaybeDef> monad, Func<T, Monad<S, MaybeDef>> f)
		{
			Just<T> just = monad as Just<T>;
			if (just != null)
				return f(just.Value);
			else
				return new Nothing<S>();
		}
	}
 
         static void Main(string[] args)
	{
            var def = new MaybeDef();
            Maybe<string> result = def.Bind(def.Unit(42), value => def.Unit(value.ToString())).ToMaybe();
         }
Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Δημοσιεύτηκε στις Κυριακή, 27 Σεπτεμβρίου 2009 2:54 μμ από το μέλος PALLADIN :: 0 σχόλια

RegEx engine in F#

Ένα από τα πολύ δυνατά χαρακτηριστικά μιας functional γλώσσας, είναι η δυνατότητα να δημιουργούμε internal DSLs κάνοντας compose combinators.

Ένα τέτοιο παράδειγμα, είναι μια regex engine που έγραψα σε F#.

Κάποιες βασικές  ιδέες  της υλοποίησης:
 - lazy computations for backtracking
 - combinators for regex composition
 - parametric polymorphism: Generic "named capture variables" and input sequences
 - Unions + Active Patterns: pattern matching and value extraction


Ακολουθεί ένα sample

#r "FSharp.PowerPack.dll"
#load "RegEx.fs"

open System
open RegEx

// example from http://www.martinfowler.com/bliki/ComposedRegex.html

type extractTags = NumberOfPoint of int | NumberOfNights of int | HotelName of string
let numberOfPoints = toInt >> NumberOfPoint
let numberOfNights = toInt >> NumberOfNights
let hotelName  = toString >> HotelName

let scoreKeyword() = string "score" => !+ space()
let numberOfPoints = !+ digit() |> group numberOfPoints
let forKeyword() = space() => string "for" => space()
let numberOfNights = !+ digit() |> group numberOfNights
let nightsAtKeyword() = spaces() => string "nights" => spaces() => string "at" => spaces()
let hotelName() = !+ any() |> group hotelName

let pattern = scoreKeyword() => numberOfPoints => forKeyword() => numberOfNights => nightsAtKeyword() => hotelName() => endOfLine()

let text = List.reduce (fun acc value -> acc + "\r\n " + value)
              [ "score 400 for 2 nights at Minas Tirith Airport"; 
                "score 500 for 6 nights at Athens Airport";
                "score 200 for 3 nights at London Airport" ] + "\r\n"

let result = patternMatch pattern text

// pattern match
match result with
| Success ( (NumberOfPoint(points) :: NumberOfNights(nights) :: HotelName(name) :: _) :: _ ) -> printfn "Points: %d, Nights %d, Hotel name: %s" points nights name
| Failure -> ()

                
let replacePattern = function
| [NumberOfPoint(points); NumberOfNights(nights); HotelName(name)] -> sprintf "score %d for %d nights at %s" (points * 2) (nights * 3) (name + " ok")
| _ -> failwith "Expected extraction pattern: score {NumberOfPoint} for {NumberOfNights} nights at {HotelName}"

let replacedResult = patternReplace pattern text replacePattern |> Array.of_seq |> (fun (chars : array<char>) -> new String(chars))
Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr

Attachment(s): RegEx.zip
Δημοσιεύτηκε στις Κυριακή, 13 Σεπτεμβρίου 2009 10:44 μμ από το μέλος PALLADIN :: 0 σχόλια

letrec

Ο Bart de smet συνεχίζει την πολύ καλή σειρά από posts, και αυτή την φορα μας παρουσιάζει ένα cache Enumerable, μαζί με έναν "let" binder.
Φυσικά λείπει το αδελφάκι "letrec", όπου έμεινε ως άσκηση για τον αναγνώστη.
(η αφορμή που έψαχνα για να ξυπνήσει Ο old schemer μέσα μου)

		delegate Func<A, R> Recursive<A, R>(Recursive<A, R> r);
		static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f)
		{
			Recursive<A, R> rec = r => a => f(r(r))(a);
			return rec(rec);
		}
		public static IEnumerable<U> Let<T, U>(this IEnumerable<T> source, Func<IEnumerable<T>, IEnumerable<U>> function)
		{
			using (var mem = new MemoizeEnumerable<T>(source))
			{
				foreach (var item in function(mem))
					yield return item;
			}
		}
		public static IEnumerable<U> LetRec<T, U>(this IEnumerable<T> source, Func<Func<IEnumerable<T>, IEnumerable<U>>, Func<IEnumerable<T>, IEnumerable<U>>> function)
		{
			Func<Func<IEnumerable<T>, IEnumerable<U>>, Func<IEnumerable<T>, IEnumerable<U>>> letWrap =
				f => x => Let(x, function(f));

			return Y(letWrap)(source);
		}
Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Δημοσιεύτηκε στις Δευτέρα, 17 Αυγούστου 2009 5:02 μμ από το μέλος PALLADIN :: 0 σχόλια

A dynamic Y Combinator

Ο Bart de Smet έγραψε ένα πολύ καλο blog post για όσους θέλουν να πάρουν μια
μικρή γεύση από την ομορφιά και την δύναμη του λ-λογισμου.

To ενδιαφέρον στην προσπάθεια είναι ότι o Bart μας παρουσιάζει την untyped εκδοχή του λογισμού χρησιμοποιώντας το dynamic feautre της C# 4.0!!!

Διαβάζοντας το post είδα ότι λείπει ο Y combinator... οποτε ορίστε μια εκδοχή που σκέφτηκα...

            Func<Func<dynamic, dynamic>, dynamic> fd = x => x;
            dynamic Y = fd(f => fd(x => f(fd(y => x(x)(y))))(fd(x => f(fd(y => x(x)(y))))));
            Y(fd(f => fd(x => f(x))))(42);


Remarks:

Επειδή ο compiler δεν με αφήνει να παω από lambda σε dynamic
dynamic f = x => x; // type error
Αντί να κάνω συνεχεια new Func<dynamic, dynamic>(x => x)(οπως γίνεται στο post), σκέφτηκα να χρησιμοποιήσω μια μικρή συνάρτηση
ώστε να προσπεράσω τον περιορισμό.
dynamic f = fd(x => x);


(Παρεμπιπτόντως, αυτή είναι η πρώτη φορα που χρησιμοποιώ το νέο dynamic feature :))

Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Δημοσιεύτηκε στις Παρασκευή, 31 Ιουλίου 2009 6:54 μμ από το μέλος PALLADIN :: 0 σχόλια

Concepts will remain concepts... for now

Τα Concepts δυστυχώς δεν θα είναι στο νέο Standard της C++.
Για μένα αυτό ήταν το πιο σημαντικό feature... θα έδινε τέλος στα απίστευτα template error messages... και θα έκανε πραγματικότητα το
όραμα του Stepanov για pure generic programming.

http://lambda-the-ultimate.org/node/3518#comment-50071

Η C++ πριν από 10 χρονια ήταν η αγαπημένη μου γλώσσα... (Είναι η γλώσσα με τα περισσότερα βιβλία στην βιβλιοθήκη μου)
Είχα πει ότι θα ξανά-γράψω C++ όταν θα έχω Concepts, δυστυχώς πλέον είναι πολύ μακριά.

Νομίζω ότι κόσμος χρειάζεται μια νέα multi-paradigm system-oriented γλώσσα.

It was The Golden Age of Grotesque

Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Δημοσιεύτηκε στις Σάββατο, 30 Μαΐου 2009 3:03 μμ από το μέλος PALLADIN :: 0 σχόλια

Functional style regex engine in F#

Κατά καιρούς συναντώ πολύ όμορφα κομμάτια κώδικα στο web. Ένα από αυτά είναι και

η toy regex engine που εντόπισα στο blog του Charles Cook.

Για το code archive μου... παραθέτω την υλοποίηση σε F# που εμπνεύστηκα

let char c (s : string) = seq { if s.Length > 0 && s.[0] = c then yield s.Substring(1) }

let (=>) l r s = seq { for sl in l s do for sr in r sl -> sr }

let (<|>) l r s = seq { yield! l s; yield! r s }

let rec (<*>) e s = seq { yield s; yield! (e => (<*>) e) s }

let (<+>) e = e => (<*>) e

// example c(a|d)+r
let pattern = char 'c' => (<+>) (char 'a' <|> char 'd') => char 'r'
Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Δημοσιεύτηκε στις Πέμπτη, 16 Απριλίου 2009 12:46 μμ από το μέλος PALLADIN :: 0 σχόλια

An F# Solution to Eric Lippert's Challenge

Ο Erik Lippert στο τελευταίο του blog post, έθεσε ένα απλό προβληματάκι.
Ακολουθεί η λύση που έκανα post.
#r "FSharp.PowerPack.dll"

let format (words : seq<string>) =
  let rec format (words : LazyList<string>) acc =
      match words with
          | LazyList.Nil -> string.Empty
          | LazyList.Cons(first, LazyList.Nil) -> first
          | LazyList.Cons(first, LazyList.Cons(second, LazyList.Nil)) -> acc + first + " and " + second
          | LazyList.Cons(first, rest) ->  acc + first + ", " |> format rest 
          
  let listOfWords = LazyList.of_seq words  
  "{" + (format  listOfWords string.Empty) + "}"


["ABC"; "DEF"; "G"; "H" ] |> format
["ABC"; "DEF" ] |> format 
["ABC"] |> format
[] |> format
Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Δημοσιεύτηκε στις Τετάρτη, 1 Απριλίου 2009 2:02 μμ από το μέλος PALLADIN :: 0 σχόλια

April fool's day

On 1 April 1925, I was sick in bed ... In the morning my brother Emile (ten years my senior) came into my bedroom and said: "Well, Raymond, today is April Fool's Day, and I will fool you as you have never been fooled before!" I waited all day for him to fool me, but he didn't.

Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Δημοσιεύτηκε στις Κυριακή, 15 Μαρτίου 2009 12:33 μμ από το μέλος PALLADIN :: 0 σχόλια

And the Oscar goes to -> Real World Haskell

“Avoid Success at All Costs!” ... ήταν το ανεπίσημο slogan της Haskell.
Οι εποχές άλλαξαν... και το platonic realm ~"αντικατοπτρίζει"~ τον πραγματικό κόσμο.
Ένα από τα καλύτερα tech-science-books που διάβασα το 2008.

 

Μοιραστείτε τη δημοσίευση: email-it! | Share on Facebook | ForaCamp.gr! | DigMe! | BobIt! | Buzz! | CheckIt! | Cull! | BlogSpace | Baza.gr | KickIt.gr
Περισσότερες Δημοσιεύσεις Επόμενη »