我有这个功能:
aantalSong song list = let lijst = filterSong song list
in teller lijst
filterSong song list = filter (==song) list
teller lijst = length lijst
我想做这样的事情:
aantalSongs song list revs = map (aantalSong song list) revs
如果我是对的那么这是不可能做到的,但最好的替代方案是什么?
答案 0 :(得分:4)
aantalSong
实际上只计算特定歌曲在歌曲列表中出现的次数。假设revs
类似于Review
的列表(对于未来的读者,请参阅上一个问题:Filter a haskell list),那么您需要将“歌曲列表获取者”与{ {1}}。
aantalSong
我们可以做很多技巧来压缩这些代码,也许可以让它更清晰。首先是一些eta减少和运动到成分风格。
aantalSongs song revs = map (\rev -> aantalSong song (topSongs rev)) revs
然后我们打开aantalSongs song revs = map (\rev -> aantalSong song (topSongs rev)) revs
aantalSongs song = map (\rev -> aantalSong song (topSongs rev))
aantalSongs song = map (aantalSong song . topSongs)
,看看我们是否可以进一步简化它。这基本上只是很多函数内联。
aantalSong
组合这些部分为我们提供了一种相对简单的功能。
aantalSong song list = let lijst = filterSong song list in teller lijst
aantalSong song list = let lijst = filterSong song list in length lijst
aantalSong song list = length (filterSong song list)
aantalSong song = length . filterSong song
aantalSong song = length . filter (== song)
在我自己的代码中,我通常会将其写为
-- | The number of times a particular song is
-- given as the 'topSong' in each review.
aantalSongs :: String -> [Review] -> [Int]
aantalSongs song = map (length . filter (== song) . topSongs)
和-- | The number of times a particular song is
-- given as the 'topSong' in a review.
aantalSongs :: String -> Review -> Int
aantalSongs song = length . filter (== song) . topSongs
在需要时列出map
。
有些人批评无点样式是混淆和“毫无意义”,但如果使用得当,我认为这样可以使代码非常精彩。