2017-11-04 18 views
0

ArtistのリストとGenreの文字列をパラメータとして受け取り、そのジャンルのすべてのArtistを出力する関数を作成しようとしています。次のように私は、データ型Artistを定義していますユーザー定義型のフィルタリング

data Artist = Artist Name Genres 
    deriving Show 
type Name = String 
type Genres = [Genre] 
type Genre = String 

次のように機能を実装するために私のコードは次のとおりです。

getFilteredArtists :: [Artist] -> Genre -> [Artist] 
getFilteredArtists xs genre = filter (genre) (map getGenres xs) 

サンプル関数の呼び出しは以下の通りです:

べき
artists = [ 
    Artist "Grimes" ["Electropop", "Dream Pop", "Synthpop"], 
    Artist "My Bloody Valentine" ["Shoegaze", "Noise Pop", "Post Punk"], 
    Artist "David Bowie" ["Art Rock", "Pop Rock", "Glam Rock", "New Wave"] 
    ] 

getFilteredArtists artists "Art Rock" 

しかし、TYPを出力している、[Artist "David Bowie" ["Art Rock", "Pop Rock", "Glam Rock", "New Wave"]

My機能を返します電子一致のエラーと私はなぜ不明です。どんな助けでも大歓迎です!

答えて

3

以下のコードは動作するはずです。あなたが何が起こっているのかについて人々がより良い考えを持つことができるように、タイプエラーを投稿すると助けになります。私はあなたのコードにいくつかの問題を見ることができます。

一つ、あなたは文字列ではなく、ブール値であるジャンル、でフィルタしようとしています。文字列を比較するには、(==)を使用する必要があります。

第二に、getGenresが定義されていないが、アーティストの上にマッピングし、それが芸術家を取り、あらゆるジャンルを返すと仮定すると、あなたのコードは、それが何をしたいと思われるものはしないだろう。それは単にアーティストのコンテキストを追加せずにジャンルを与えるだけです。

は、私はあなたがジャンルは、現在の作家の要素であるアーティストをフィルタリングされて何をしたいかと思います。

また、手動でそれらを記述することなく、自動的に作るあなたのためのアクセサ関数を作るためのデータ宣言を使用することができます。

data Artist = Artist { 
    getName :: String, 
    getGenres :: Genres 
} deriving (Show) 

type Name = String 
type Genres = [Genre] 
type Genre = String 

getFilteredArtists :: [Artist] -> Genre -> [Artist] 
getFilteredArtists xs genre = filter (\x -> genre `elem` getGenres x) xs 

artists = [ 
    Artist "Grimes" ["Electropop", "Dream Pop", "Synthpop"], 
    Artist "My Bloody Valentine" ["Shoegaze", "Noise Pop", "Post Punk"], 
    Artist "David Bowie" ["Art Rock", "Pop Rock", "Glam Rock", "New Wave"] 
    ] 

main = print $ getFilteredArtists artists "Art Rock" 

上記のコードが出力さ:

[Artist {getName = "David Bowie", getGenres = ["Art Rock","Pop Rock","Glam Rock","New Wave"]}] 
3
genre :: Genre 
filter :: (a -> Bool) -> [a] -> [a] 
filter genre :: ??? 

代わりに、何が必要hasGenreの書き方を

getFilteredArtists xs genre = filter hasGenre xs where 
    hasGenre :: Artist -> Bool 

のような述語のですか?さて、あなたはすでにgetGenres機能を持っており、標準ライブラリは

elem :: Eq a => a -> [a] -> Bool 

機能を持っています。それ以外の場合はFalseに含まれている場合はgenre `elem` genres == Truegenreの場合はgenresになります。