Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# properties design

Tags:

f#

So when ever im creating some properties in my F# code , as F# doesn't support auto properties , as far as i know. I have to create backing fields and initialize them to null, which doesn't seems right in functional programming terms. For e.g.


 let mutable albums : DbSet = null
 let mutable genres : DbSet = null

member x.Albums 
    with get() = albums
    and set(value) = albums <- value


member x.Genres
    with get() = genres
    and set (value) = genres <- value

Is there a better way of doing this ?. Many thanks for your suggestions.

like image 754
netmatrix01 Avatar asked Feb 08 '12 08:02

netmatrix01


2 Answers

F# does not support auto properties when you need a mutable property, but it supports a lightweight syntax when you need just a readonly property. If you're writing some functional code, then using readonly properties might actually be more appropriate:

type Music(genres : DbSet, albums : DbSet) = 
  member x.Albums = albums
  member x.Genres = genres

This is essentially the same as records suggested by pad, but it may be more appropriate if you want to have better control over how the types look (and how they appear in C#, or for data-binding).

If DbSet is a mutable type, then you probably can just use the above type and initialize it just once (you'll still be able to modify the DbSet values). If you want to change the DbSet value, you can add a method that returns a cloned object:

  member x.WithAlbums(newAlbums) = 
    Music(genres, newAlbums)

Using null or Unchecked.defaultOf<_> in F# is considered a very bad practice and you should always try to create fully initlized object. If the value may be missing, you can use option type to represent that, but then you have to always write handler for missing value, to make your program safe.

like image 169
Tomas Petricek Avatar answered Oct 06 '22 01:10

Tomas Petricek


FYI - auto-properties are planned for F# 3.0. See the preview documentation [MSDN]. Looks like your example would become:

type Music() =
  member val Albums : DbSet = null with get, set
  member val Genres : DbSet = null with get, set
like image 22
Daniel Avatar answered Oct 05 '22 23:10

Daniel