Skip to content

Instantly share code, notes, and snippets.

@rhwlo
Last active October 6, 2015 19:57
Show Gist options
  • Save rhwlo/10e554d8d8acfe3dcb38 to your computer and use it in GitHub Desktop.
Save rhwlo/10e554d8d8acfe3dcb38 to your computer and use it in GitHub Desktop.
Adding section/page markers to a list
{- I’m trying to add section/page markers to a list of Monoids. In the first
case here, the Monoids are actually strings, but in the second, they aren't. -}
{- Case #1 -}
import Data.Char (chr)
sectionLength :: Int
sectionLength = 3
myVocab :: [String]
myVocab = [ "android", "aardvark", "arrogant"
, "behemoth", "Beelzebub", "brilliant"
, "carrion", "cretaceous", "cerulean"
, "diadem", "demented", "Derrida" ]
makeVocabHeader :: Int -> String
makeVocabHeader n = chr (n + 65):": "
makeVocabSection :: [String] -> Int -> String
makeVocabSection vocab offset = let
vocabSectionVocab :: [String]
vocabSectionVocab = take sectionLength $ drop (sectionLength * offset) vocab
in unwords (makeVocabHeader offset:vocabSectionVocab)
makeVocabSections :: [String] -> String
makeVocabSections vocab = unlines (makeVocabSection vocab <$> [0..(length vocab `div` sectionLength - 1)])
myVocabWithSections :: String
myVocabWithSections = makeVocabSections myVocab
{- Case #2 -}
-- apologies for the ugly type signature; Yesod yields these.
formatWithDogears :: (MonadIO m, MonadBaseControl IO m, MonadThrow m)
=> (Entity Entry -> WidgetT Scarlet m ())
-> Int
-> Int
-> [Entity Entry]
-> WidgetT Scarlet m ()
formatWithDogears formatter pN offset entries = let
section :: Int -> [a] -> [[a]]
section _ [] = []
section n xs = take n xs:section n (drop n xs)
formattedEntries = formatter <$> entries
dogEars = [ formatDogear n | n <- [offset..] ]
in
mconcat $ join $ zipWith (:) dogEars (section pN formattedEntries)
{- As a few final remarks: I don’t really like the first version because
using `unlines` and `unwords` just hide the `join`/`mconcat`s; and
I think that breaking out `section` into its own function probably
makes more sense than leaving it inline with the `take ... drop ...`
construction in Case #1.
But in the Case #2, I really don’t like the `mconcat $ join` or
`join $ join`, because chaining together mconcat and join to me
feels like code smell: if I break things into Mon{a,oi}ds and then
recombine them, couldn’t I have just changed them as they were in
the first place?
I would greatly appreciate any insight! -}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment