2012-02-08 12 views
2

私はこの種の質問を早く受けました。しかし残念なことに、私は差別化された組合をどのように設計するのかを本当に理解することができません。F#分別された組合を理解する

ので、私は

 

type Artist(artistId : int, name : String) = do if name = null then nullArg String.Empty new(artistId: int) = Artist(artistId) member x.ArtistId = artistId member x.Name = name

and Genre() = let mutable name = String.Empty let mutable genreId : int = 0 let mutable description = String.Empty let mutable albums = List.empty 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 albumId = 0 let mutable genreId = 0 let mutable artistId = 0 let mutable price : decimal = Decimal.Zero let mutable albumArtUrl = String.Empty let mutable genre = new Genre() let mutable artist = new Artist(artistId) 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

enter code here

I tried defining the above as a Discriminated union based on suggestions by some of F# guru's

which i defined like below

type Name = string type AlbumId = int

type Artist = | ArtistId of int | Artist of Name

type Album = | Title of string | Price of decimal | Album of AlbumId * Artist | AlbumArtUrl of string

type Genre = | GenreId of int | Genre of Name * Album list

enter code here

しかし、私は私の区別組合も同様に、私はちょうど性質である私の単純なF#の型でやっていた?移入する方法を見つけ出すことが、今、私ができないように見えるデータ構造の束を持っていますか。

誰かがこれを説明するのを助けることができますか?私は差別化された組合について読んできましたが、私が完全に理解しているとは言いません。

+1

あなたが最近尋ねてきたすべてのF#の質問を考慮すると、この時点で、F#でWikibookを読むのは本当に価値があります。(推定可能な@Julietによって書かれている)、またはF#の本に投資する。 JulietのWikibookはかなり良いので、そこから始めたいと思うかもしれません。しかし、不快感はありませんでした。あなたは時間をかけて、いくつかのファンダメンタルズを落とすことをお勧めします。もしあなたがそうしたら、あなたはF#をもっとよく把握するでしょう。 –

答えて

6

識別された共用体は、オブジェクト指向のランゲージのクラス階層にほぼ対応する、複数の異なるケースを持つ型を表すために使用されます。

type Shape = 
    | Rectangle of (float * float) * (float * float) // Carries locations of two corners 
    | Circle of (float * float) * float    // Carries center and diameter 

あなたの判別組合は本当にあなたがおそらく意図何をしません定義された方法:たとえば、CircleRectangleための2つの継承されたクラスと基底クラスShapeは、次のように定義されるかもしれません。あなたのタイプAlbumArtistおよびGenreはただ1つの具体的なタイプを表します。

あなたは、または単一のクラスに対応して一つのケース、と区別組合を使用して(単に軽量ちょうど性質を持つクラスのようなもの)のいずれかのレコードを持つこれらを表現しているが、かなり軽量な構文を持つことができます主な利点。たとえば:

type Name = string 
type Price = decimal 
type AlbumId = int 
type ArtistId = int 

type Artist = Artist of ArtistId * Name 
type Album = Album of AlbumId * Name * Price * Artist 

は数枚のアルバムと一緒にアーティストを構築するために、次のように記述することができます:あなたは、その後ジャンルを作成した場合、それはアルバムのリストとの可能性のリストが含まれます

let pinkFloyd = Artist(1, "Pink Floyd") 

let darkSide = Album(1, "The Dark Side of the Moon", 12.0M, pinkFloyd) 
let finalCut = Album(2, "The Final Cut", 11.0M, pinkFloyd) 

あなたは次のようなものを書くことができます:

type Genre = Genre of Name * Artist list * Album list 

let rock = Genre("Rock", [pinkFloyd], [darkSide; finalCut]) 

質問は今実際どのようにタイプしたいですか?あなたのデータソースは何ですか?データベースやXMLファイルからデータをロードする場合は、データソースの一部を取り、関数ArtistまたはAlbumを返す関数を作成し、すべてのアルバムとアーティストを読み込んだ後、それらをGenreを入力し、最終結果として返します。

PS:実際にあなたがしようとしていることのより大きなイメージを与えるわけではないので、あなたの質問に答えるのは少し難しいです。小さいながらも具体的な例(データのロードとその使用を含む)を与えることができれば、誰かが、より機能的な観点から問題を見るのを助けることができます。

+0

ああ本当にごめんなさい@トーマス、私は自分の問題/質問を理解することが難しいことを意味しませんでした。私が試みているのは、このチュートリアルのhttp://mvcmusicstore.codeplexに従うことです。com、あなたが好きな場合は、C#にあるPDFをダウンロードし、アプリケーションをF#に変換することができます。厳密に同じアプリケーションは、プロセス内で関数型プログラミング/ F#を学びたいだけです。 – netmatrix01

+0

あなたは、差別化された組合と私たちが達成できるものを理解するのにかなり役立ちました。しかし、どのように私のタイプは、相互に再帰的ですこの問題を解決するだろう。ジャンルタイプには、アルバムもプロパティとして含まれています。差別化された共用体を使用してドメインを定義する場合、これは可能ですか? – netmatrix01

+3

@ netmatrix01相互に再帰的な型を使用する場合は、通常、突然変異とクラスが必要です。しかし、あなたの 'Album'sが' Genre'に保存されている場合、本当に 'Album'から' Genre'への参照を保存する必要がありますか?たとえば、あなたがリストするとき。指定されたジャンルのアルバムがあれば、そのジャンル名はいつでも知ることができます。同様に、特定のアルバムを表示するときに、オブジェクト構造を見ていると、そのジャンルを常に知ることができます。だから、私はおそらく、この種のアプリケーションで再帰構造を避けるようにしようと考えています。 –

関連する問題