2012-02-06 7 views
1

私の型の階層がVisual Studioで型の並べ替えを処理していないサンプルアプリケーションをビルドしています。どのような方法でファイルを整理しようとしても(上、下)、すべてのクラスを定義することはできません。F#クラスの並べ替えVisual Studio

そこで彼らは、F#プロジェクトで

type Artist() = 
    let mutable artistId = 0 
    let mutable name = String.Empty 

    member x.ArtistId 
     with get() = artistId 
     and set (value) = artistId <- value 

    member x.Name 
     with get() = name 
     and set (value) = name <- value 

type Genre() = 
    let mutable name = String.Empty 
    let mutable genreId = 0 
    let mutable description = String.Empty 
    let mutable albums = [new Album()] 

    member x.Name 
     with get() = name 
     and set (value) = name <- value 

    member x.GenreId 
     with get() = genreId 
     and set (value) = genreId <- value 

    member x.Description 
     with get() = description 
     and set (value) = description <- value 

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

and Album() = 
    let mutable title = String.Empty 
    let mutable genre = new Genre() 
    let mutable albumId = 0 
    let mutable genreId = 0 
    let mutable artistId = 0 
    let mutable price : decimal = Decimal.Zero 
    let mutable albumArtUrl = String.Empty 
    let mutable artist = new Artist() 

    member x.Title 
     with get() = title 
     and set (value) = title <- value 

    member x.Genre 
     with get() = genre 
     and set (value) = genre <- value 

    member x.AlbumId 
     with get() = albumId 
     and set (value) = albumId <- value 

    member x.GenreId 
     with get() = genreId 
     and set (value) = genreId <- value 

    member x.ArtistId 
     with get() = artistId 
     and set (value) = artistId <- value 

    member x.Price 
     with get() = price 
     and set (value) = price <- value 

    member x.AlbumArtUrl 
     with get() = albumArtUrl 
     and set (value) = albumArtUrl <- value 

    member x.Artist 
     with get() = artist 
     and set (value) = artist <- value 

あるために、したがって、上記の場合には、私はエラー「アルバム」が定義されていません取得します。

これを解決する方法はありますか。それとも、私のタイプの階層構造の全体を再考する必要がありますか?

+0

そこで、基本的ジャンルのタイプは、アルバムとアルバムの種類はフィールドとしてジャンルを含むリストが含まれています。 F#でこのような階層を定義することは、何とか可能ですか? – netmatrix01

+3

完全な答えを書くのに快適なコンピュータの近くではなく、簡単に言えば、同じモジュール/名前空間に型を置くと、相互に再帰的な型を持つことができます。それらを順番に並べて、2番目の "type"キーワードをキーワード "and"に置き換えてください。 F#の種類に関するMSDNの記事に行くと、より完全な説明が得られます。 –

答えて

5

相互に再帰的なという2つのタイプ(互いに参照できるという意味)を定義する必要がある場合は、それらを1つのファイルに配置して、type ... and ...構文を使用する必要があります。あなたの例では

、これはGenreAlbumは次のように定義する必要があることを意味します

// Start a definition block using 'type' as normal 
type Genre() = 
    let mutable name = String.Empty 
    let mutable albums = [new Album()] 

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

// Continue single type definition block using 'and' 
and Album() = 
    let mutable genre = new Genre() 
    let mutable albumId = 0 
    let mutable artist = new Artist() 

    member x.Genre 
     with get() = genre 
     and set (value) = genre <- value  
    member x.AlbumId 
     with get() = albumId 
     and set (value) = albumId <- value  
    member x.Artist 
     with get() = artist 
     and set (value) = artist <- value 

しかし、あなたの例は非常にC#のスタイルにF#を使用しているので、コードは実際には非常に見ていませんエレガントであり、関数型プログラミングのメリットの多くを与えるわけではありません。

私が使用している構造を表現したければ、おそらくAlbumタイプにそのジャンルへの参照を追加しません。 Genreの中にアルバムのリストを置くと、データ構造を処理するとき(つまり、データバインディングに渡すことができる他の構造、おそらくF#レコードに変換するときに)、そのジャンルをいつでも復元することができます。 。 F#の恩恵は、ドメインを数行書くことができるということですが、それは機能型に対してのみ機能します。一つのケースで判別共用体を使用して

、あなたが書くことができます。

// Type aliases to make code more readable 
type Name = string 
type AlbumID = int 

// Simple type definitions to represent the domain 
type Artist = Artist of Name 
type Album = Album of AlbumID * Artist 
type Genre = Genre of Name * Album list 
+0

ああクール、それを試して考えていた、私は以前のどこかで、忘れてしまったことを読んだと思う。多くのありがとう – netmatrix01

+0

しかし私は別々のファイルでタイプを分離するよりきれいな方法を持っているべきだと思います。今のところうまくいきません。大したファイルは扱いづらいかもしれません。 – netmatrix01

+1

@ netmatrix01大きなプロジェクトでは、インターフェイスを使用する必要があります。 'Genre'と' Album'を(単一のファイル内に)インタフェースとして定義し、実際の実装をより多くのファイルに分割し、これらのインタフェースを参照することができます。 –

関連する問題