Hi,

as already mentioned, the problem with design patterns is that they make sense mostly in "pure" object oriented environment like Java or C#. I agree that it would be very interesting to find what are good design patterns in functional programming. For F# we have to go a bit furthere, because it allows you to write mixed OO & functional code, so we need good mixed design patterns.

For the abstract factory, you may try something like following:
(however, the idea behind abstract factory is that you want to create implementation of abstract type/interface, which may not always be the most suitable abstraction in F# - in this sample I use GUI controls, where I think using interfaces makes very good sense).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 

#light

// Abstract interfaces for Button and Label 
type IButton =
  interface
    abstract member GetCaption : unit -> string
    abstract member SetCaption : string -> unit
    abstract member Draw : unit -> unit
  end

type ILabel =
  interface
    abstract member Draw : unit -> unit
  end

// Factory is a set of functions for creating concrete implementations    
type Factory = 
  { createButton : unit -> IButton;
    createLabel  : unit -> ILabel }

// Windows factory - returns Factory with a windows functions
// (interfaces are implemented using F# object expressions)        
let windowsFactory = 
  { createButton = fun () -> 
      let capt = ref ""
      { new IButton 
        with Draw()       = printfn "Windows button [%s]" !capt
        and GetCaption()  = !capt
        and SetCaption(v) = capt := v };
    createLabel = fun () ->
      { new ILabel 
        with Draw()       = printfn "Windows label!" } }

// MacOS factory - returns Factory with a Mac functions
let macFactory = 
  { createButton = fun () -> 
      let capt = ref ""
      { new IButton 
        with Draw()       = printfn "MacOS button [%s]" !capt
        and GetCaption()  = !capt
        and SetCaption(v) = capt := v };
    createLabel = fun () ->
      { new ILabel 
        with Draw()       = printfn "MacOS label!" } }
        
// Gives factory for specified OS        
let factory os = 
  match os with
  | "Windows" -> windowsFactory
  | "Mac" -> macFactory
  | _ -> failwith "Sorry!"
  
  
// DEMO  
let f1 = factory "Windows"
let f2 = factory "Mac"
let b1 = f1.createButton()
let b2 = f2.createButton()

b1.SetCaption("Hi there!")
b2.SetCaption("Hi there!")
b1.Draw();
b2.Draw();

Hope this helps a bit,
Tomas

By on 6/11/2007 6:44 AM ()

Don't forget that most object-oriented design patterns are redundant in a functional programming language like F#.

For example, the (incomplete!) hundred line example for the "abstract factory pattern" by the GoF translates into four lines of F#:

1
2
3
4
5
type carnivore = Lion | Wolf
type herbivore = Wildebeest | Bison

let eats predator prey =
  any_to_string predator^" eats "^any_to_string prey

I think it would be a good exercise to work out which OO design patterns correspond to which functional programming constructs and translate the examples accordingly.

By on 6/10/2007 3:27 PM ()

Don't forget that most object-oriented design patterns are redundant in a functional programming language like F#.

For example, the (incomplete!) hundred line example for the "abstract factory pattern" by the GoF translates into four lines of F#:type carnivore = Lion | Wolf
type herbivore = Wildebeest | Bison

let eats predator prey =
any_to_string predator^" eats "^any_to_string prey

I think it would be a good exercise to work out which OO design patterns correspond to which functional programming constructs and translate the examples accordingly.

First of all, I want do undestand how can I write in F# like in C# OO style, next step to simplify it with functional programming features.
I don't understand how use the Predator example?

By on 6/11/2007 5:13 AM ()

Don't forget that most object-oriented design patterns are redundant in a functional programming language like F#.

For example, the (incomplete!) hundred line example for the "abstract factory pattern" by the GoF translates into four lines of F#:

1
2
3
4
5
type carnivore = Lion | Wolf
type herbivore = Wildebeest | Bison

let eats predator prey =
  any_to_string predator^" eats "^any_to_string prey

I think it would be a good exercise to work out which OO design patterns correspond to which functional programming constructs and translate the examples accordingly.

First of all, I want do undestand how can I write in F# like in C# OO style, next step to simplify it with functional programming features.
I don't understand how use the Predator example?

I think what Jon means is that there are some patterns in OO programing that aren't actually patterns in a functional language like F# as they are either a feature of the langauge or they can be encapsulated by a single library function. Take the iterator pattern for example ([link:en.wikipedia.org]), now reduntant in many languages, not just functional ones. In F# this can be replaced by a single call to Seq.iter or use the build it list comprehensions (for x in list do ...).

So the challenge is not to wirte F# like C# OO then simplify it, but go though existing design patterns and say that pattern can be replace by XXX feature or F# or this pattern can be replaced a call to the function YYY. I think this is a fairly changeling task requiring you to know both design patterns and F# very well, also I don't think you'll be able to do this for every pattern, but I think that there is some where you can.

Jon predator example is simple to use:

1
eats Lion Wildebeest 

I'm not that famillar with the "Abstract Factory Pattern", but I think the point he is trying to make is that the "abstract factory pattern" resembles F#'s union types.

By on 6/11/2007 6:20 AM ()
1
eats Lion Wildebeest 

I'm not that famillar with the "Abstract Factory Pattern", but I think the point he is trying to make is that the "abstract factory pattern" resembles F#'s union types.

But how use union types than it become the Abstract Factory Pattern? I think without inheritance it's imposible.

By on 6/11/2007 8:04 AM ()
By on 6/11/2007 10:02 AM ()

fwiw [link:people.csail.mit.edu]

Thanks for sharing! This is a very interesting work! OCaml is very close to F#, so it is definetly useful, but I still think that in F# it is sometimes benefitial to use some of the F# "object oriented" constructs, however it has to be carefuly evaluated when it makes sense.

Saddly, functors (used for abstract factory) are one of the OCaml constructs that are not available in F#. You can write similar code be generalizing the code I posted earlier.

By on 6/11/2007 10:19 AM ()

I think it would be a good exercise to work out which OO design patterns correspond to which functional programming constructs and translate the examples accordingly.

This is true, and I'd say that functional programing has its own set of design patterns as well. For example a common pattern I see is the use of an auxiliary function to with an accumilator parameter that is then hidden from the functions users. For example this definition of the library function rev_map:

1
2
3
4
5
6
7
#light
let rev_map f l = 
    let rec rev_map_acc f l acc =
      match l with 
      | [] -> acc
      | h::t -> rev_map_acc f t (f h :: acc)
    rev_map_acc f l []

There's probably others out there, but thats the only one I can think of off the top of my head. I know there has been some academic work in this area: [link:www.cs.vu.nl], but personally I don't find this paper very easy reading. It would certainly to see OO design patterns mapped to F# constructs along with a set of design patterns in F#. But I think this would be difficult task.

By on 6/11/2007 2:24 AM ()

One problem
1) override x.Display depth = Console.WriteLine(new String('-', depth) + x.Name)
Than get name field Component class, I create property Name. Can I do something than field name be available in child class?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
--------------------------- Composite --------------------------------------------

open System
type Component(s: string) = class
    let mutable name = s
    member x.Name
      with get() = name
      and  set(v) = name <- v
    abstract Add: Component -> unit
    abstract Remove: Component -> unit
    abstract Display: int -> unit
    end
    
type Composite(s: string) = class
    inherit Component(s)
    let mutable children = []
    override x.Add com = children <- children @ [com]
    override x.Remove com = children <- List.filter (fun c -> c <> com) children
    override x.Display depth = Console.WriteLine(new String('-', depth) + x.Name)
                                           List.iter (fun (com : Component) -> com.Display(depth + 2)) children
    end

type Leaf(s) = class
    inherit Component(s)
    override x.Add com = Console.WriteLine("Cannot add to a leaf")
    override x.Remove com = Console.WriteLine("Cannot remove from a leaf")
    override x.Display depth = Console.WriteLine(new String('-', depth) + x.Name)
    end

open Composite

let root = new Composite("root");
root.Add(new Leaf("Leaf A"));
root.Add(new Leaf("Leaf B"));

let comp = new Composite("Composite X");
comp.Add(new Leaf("Leaf XA"));
comp.Add(new Leaf("Leaf XB"));

root.Add(comp);
root.Add(new Leaf("Leaf C"));

// Add and remove a leaf
let leaf = new Leaf("Leaf D");
root.Remove(leaf);

// Recursively display tree
root.Display(1);
By on 6/10/2007 12:37 AM ()

2) If replace

for com in children do com.Display(depth + 2) done

on

List.map (fun com -> com.Display(depth + 2)) children

Function signature change to

int -> a' list

What do I set in end of function, than it become int -> unit ?

When you need to explicitely ignore a value, just call the "ignore" ('a -> unit) function. Here you don't need it: the map function creates a new map. If you just want to iterate over a list, use List.iter ('a list -> unit).

For F# code highliting in the forum, I've got a button for that in design mode (but I think it depends on your options - I don't know where I got it).
In both Design and HTML mode, you can also try this tag: [ code language="F#"] let id x = x </code>

By on 6/11/2007 1:37 AM ()

just call the "ignore" ('a -> unit) function.

I don't understand want it means. Can you write the code?

By on 6/11/2007 5:25 AM ()

I don't understand want it means. Can you write the code?

1
List.map (fun com -> com.Display(depth + 2))

returns a List.

1
ignore (List.map (fun com -> com.Display(depth + 2)))

calls the List.map function and ignores return value

1
List.map (fun com -> com.Display(depth + 2)) |> ignore

the same

1
List.iter (fun com -> com.Display(depth + 2))

the same, but prettier

Laurent.

By on 6/13/2007 2:23 PM ()

First you need to use Internet Explorer to get code highlights, than simply copy paste from Visual Studio.

For getting base class try to reference it by base alias

1
2
3
4
5
6
7
8
type Composite(s: string) = class
   inherit Component(s) as base
   let mutable children = []
   override x.Add com = children <- children @ [com]
   override x.Remove com = children <- List.filter (fun c -> c <> com) children
   override x.Display depth = Console.WriteLine(new String('-', depth) + base.Name)
                                          for com in children do com.Display(depth + 2) done
end

For your second question this is because of type inference. You can read more from this thread

Hope this helps.

Can.

By on 6/10/2007 4:18 PM ()

For getting base class try to reference it by base alias

type Composite(s: string) = class
inherit Component(s) as base
let mutable children = []
override x.Add com = children <- children @ [com]
override x.Remove com = children <- List.filter (fun c -> c <> com) children
override x.Display depth = Console.WriteLine(new String('-', depth) + base.Name)
for com in children do com.Display(depth + 2) done
end

I don't want create the

1
2
3
4
5
6
7
 member x.Name


      with get() = name


      and  set(v) = name <- v

and I wand get access to parent field like base.name but it is not available.

By on 6/11/2007 5:17 AM ()

For getting base class try to reference it by base alias

type Composite(s: string) = class
inherit Component(s) as base
let mutable children = []
override x.Add com = children <- children @ [com]
override x.Remove com = children <- List.filter (fun c -> c <> com) children
override x.Display depth = Console.WriteLine(new String('-', depth) + base.Name)
for com in children do com.Display(depth + 2) done
end

I don't want create the

1
2
3
 member x.Name
      with get() = name
      and  set(v) = name <- v

and I wand get access to parent field like base.name but it is not available.

Could you please try to read red highlighted code.

By on 6/11/2007 5:35 AM ()

Could you please try to read red highlighted code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
type Component(s: string) = class
    let mutable name = s
    
    abstract Add: Component -> unit
    abstract Remove: Component -> unit
    abstract Display: int -> unit
    end
    
type Composite(s: string) = class
   inherit Component(s) as base
   let mutable children = []
   override x.Add com = children <- children @ [com]
   override x.Remove com = children <- List.filter (fun c -> c <> com) children
   override x.Display depth = Console.WriteLine(new String('-', depth) + base.Name)
                              for com in children do com.Display(depth + 2) done
   end

Error 1 The field, constructor or member 'Name' is not defined.
What am I doing wrong?

By on 6/11/2007 7:54 AM ()

As Tomas said, your base class does not have Name member to override. let mutable name is a private field. Here is the base class implementation (same as you did previously, don't know why you've removed name member)

type Component(s: string) = class
let mutable name = s
member x.Name
with get() = name
and set(v) = name <- v
abstract Add: Component -> unit
abstract Remove: Component -> unit
abstract Display: int -> unit
end

By on 6/11/2007 4:45 PM ()

don't know why you've removed name member

In other words I want to have protected member name, but I see it's imposible.

By on 6/12/2007 1:48 AM ()

It is possible : declare a member as any oher, but remove it from he signature file. The issue is that you can then only inherit this member from within the said file (ie not from an external one).

1
2
3
4
5
6
7
8
 
//file.fsi
type foo = class new: unit -> foo end
type bar = class new: unit -> bar end

//file.fs
type foo () = class member x.run() = print_string "foo()" end
type bar () = class inherit foo as base override x.run() = (base.run(); print_string "\n----\n bar()!") end 
By on 6/12/2007 11:39 PM ()

An alternate approach is to use an explicit constructor:

type Component = class
val mutable Name : string
new(s) = { Name = s; }
abstract Add : Component -> unit
// rest of abstracts
end

By on 6/11/2007 8:26 PM ()

Hi,

The problem with this example is that the Component type doesn't expose the name publicly (local values declared using "let" are private). To fix it just add the following line to the component:

member x.Name = name

However, I would probably use slightly different way for writing this in F# (it is not a criticism, just a comment how I personally would do it, because there are only a few established design patterns that you could follow).

First, I don't understand why there are "Add" and "Remove" methods in the Component - I think these should be only in the Composite type. In F# you can write function that takes sequence (list or array) of components and returns component that behaves like composite without writing the Composite type explicitly. This is very easy to write, so you might prefer this way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 

open System

type IComponent = interface
    abstract Display : int -> unit
  end
    
let compose (children:seq<IComponent>) =
 { new IComponent 
   with Display(depth) =
     Console.WriteLine(new String('-', depth) + "Composite component")
     for c in children do c.Display(depth+2) }<BR< P> 

// to use it you can write:
let cm = compose [ component1; component2; component3; ]

You can find some more information about the syntax I used at the end of this page: [link:research.microsoft.com]

By on 6/11/2007 10:12 AM ()

Good job ais.

My suggestion will be to use inline class definition to make the code more readable. For instance :

1
2
3
4
5
6
7
8
9
10
11
type Client = class
    val mutable abstractProductA: AbstractProductA
    val mutable abstractProductB: AbstractProductB
    new(fac: AbstractFactory) = {abstractProductA = fac.CreateProductA();
                                abstractProductB = fac.CreateProductB()}    member x.Run = x.abstractProductB.Interact(x.abstractProductA)
 end
 type Client (fac: AbstractFactory) = class
    let mutable abstractProductA = fac.CreateProductA()
    let mutable abstractProductB = fac.CreateProductB()
    member this.Run = abstractProductB.Interact(abstractProductA)
 end

Both of the definitions are identical, but I think the second one is easy to read and write.It's not an issue it's just the coding style. For the bridge pattern you made a little mistake while assigning implementor property.Since it's a mutable variable you need to assign using mutable operator (<-) ab.Implementor <- Some(new ConcreteImplementorA():> Implementor)ab.Operation() ab.Implementor <- Some(new ConcreteImplementorB():> Implementor)ab.Operation() Hope this helps.Can.</code>

By on 6/9/2007 4:57 AM ()

Big thanks, your Client class really look better.
One question, how can I hightlight the code?

By on 6/9/2007 11:35 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper