I’m doing a project that aims to create a PDF using the exiftool library and language Haskell and I have some doubts in the creation of functions to order the files. My work originates as PDF now lacks the sorting functions. For example for my dat.hs file contains these files (music, videos)
Files {files = [{filename = Video "-4th_dan trailer.mp4" size = "15 MB" ftype = "MP4" copyright = "-" height = "-", width = "720"}
Video {filename = "TheLostInterview.mp4" size = "73 MB" ftype = "MP4" copyright = "-" height = "Bruce_Lee_-_The_Lost_Interview.avi" width = "240"}
Audio {filename = "8bp017-08-nullsleep-humdrumz.mp3" size = "1984 kb", ftype = "MPG / 3" copyright = "-", title = "humdrumz" artist = "nullsleep", year = "2001"}
Audio {filename = "8bp017-04-nullsleep-fluffy_nougat.mp3" size = "1501 kb", ftype = "MPG / 3" copyright = "-", title = "fluffy nougat," artist = "nullsleep" year = "2001"}
I now through functions such as sortOn :: (Ord b) => (a -> b) -> [a] -> [a] and select ((> 500). size) (dat files) have to organize these files by size, year, artist …
Now one problem is the size because I want to sort by size and the size he is set to “15 MB” the MB has to be able to sort out there to
`
If I understood correctly, you want
15 MBto be considered bigger than1984 kb.One way to do this would be to use
sortByrather thansortOn.sortBytakes a comparison function and sorts using that. So you can just write a function that can sort values like15 mbproperly.However, this is not the best way to do it. Instead, I suggest you normalize all the sizes to one unit (kb, perhaps). So go through and convert
15 MBto kilobytes and store it as a number. Then, when you need to print the sizes, have a function that takes a number of kb and prettifies it. This will allow you to easily sort on size.A way to do this would be to create a
Sizetype:Then you can make it an instance of
Showto get the pretty printing working:To get the size from the input string, you could make it an instance of
Read.You can include variants of unit names (e.g. “mB” and “MB”) just by adding more pairs to
unitSizes. Any unit abbreviation not in the list is just ignored.Edit: Made the code neater by using Daniel Wagner’s suggestion.
Additional notes:
Once you’ve defined
Sizeand made it an instance of all of those type classes, you can use normal sorts on it. You can usereadon things like"10 mB"to get the size. If you usederiving (show)on your original data type, it should still work when you replace your strings withSizes.