Hacker News new | comments | show | ask | jobs | submit login

    flatten :: ByteString -> [ (String, Int, Int, String) ]
    flatten json = case decode json of
      Nothing -> []
        -- Type inference here can infer that we're using `val` as
        -- :: HashMap String (HashMap String (HashMap String String))
      Just val ->
        let books = ["Genesis", "Exodus" {- ...and so forth -} ]
        in [ (book, chNum, vsNum, verse)
              -- for every book in the list of books...
           | book <- books
               -- find the corresponding map
           , Just bookMap <- [HM.lookup book val]
               -- for every number in the range [1..max] for chapters
           , chNum <- [1..HM.size bookMap]
               -- pull that map out of the submap
           , Just chMap <- [HM.lookup (show chNum) bookMap]
               -- ...and for every number in the range [1..max] for verses
           , vsNum <- [1..HM.size chMap]
               -- ...pull the verse out of the sub-sub map
           , Just verse <- [HM.lookup (show vsNum) chMap]
Okay, this isn't as type-safe or signed-in-triplicate as the supplied Haskell solution, but if we're comparing size-to-size, then this is pretty terse while also avoiding partial functions (the supplied Haskell solution uses read, which can throw an error if we happen to have a non-numeric key in the wrong place) and still working within the restrictions of what was given.

One thing true of all bugs, it passed the type checker.

Applications are open for YC Summer 2018

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact