Skip to content

Instantly share code, notes, and snippets.

@cstrahan
Forked from honza/gist.md
Last active September 16, 2016 05:00
Show Gist options
  • Save cstrahan/5d820ce0a19af4f8ab9ed5be9b6b2e5a to your computer and use it in GitHub Desktop.
Save cstrahan/5d820ce0a19af4f8ab9ed5be9b6b2e5a to your computer and use it in GitHub Desktop.
Clojure vs Haskell

Haskell vs Clojure

The JSON data is in the following format

{
    "Genesis": {
        "1": {
            "1": "In the beginning..." ,
            "2": "..."
        },
        "2": { ... }
    },
    "Exodus": { ... },
    ...
}

In JSON, keys aren't ordered and must be strings.

The goal is to parse the JSON file, order everything correctly (which means parsing the keys into integers), and produce an array that looks like this:

[
    ("Genesis", 1, 1, "In the beginning..")
    ("Genesis", 1, 2, "")
]

The data structure can be a tuple or some new type.

Clojure

(ns versify.core
  (:require [cheshire.core :refer :all])
  (:gen-class))

(def book-order ["Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy",
    "Joshua", "Judges", "Ruth", "1 Samuel", "2 Samuel", "1 Kings", "2 Kings",
    "1 Chronicles", "2 Chronicles", "Ezra", "Nehemiah", "Esther", "Job",
    "Psalms", "Proverbs", "Ecclesiastes", "Song of Solomon", "Isaiah",
    "Jeremiah", "Lamentations", "Ezekiel", "Daniel", "Hosea", "Joel", "Amos",
    "Obadiah", "Jonah", "Micah", "Nahum", "Habakkuk", "Zephaniah", "Haggai",
    "Zechariah", "Malachi", "Matthew", "Mark", "Luke", "John", "Acts",
    "Romans", "1 Corinthians", "2 Corinthians", "Galatians", "Ephesians",
    "Philippians", "Colossians", "1 Thessalonians", "2 Thessalonians",
    "1 Timothy", "2 Timothy", "Titus", "Philemon", "Hebrews", "James",
    "1 Peter", "2 Peter", "1 John", "2 John", "3 John", "Jude", "Revelation"])

(defn intify [m]
  (apply assoc (sorted-map)
         (mapcat 
           (fn [[k v]]
             [(read-string k), v]) m)))

(defn get-books [bible]
  (map (fn [book] [book, (bible book)]) book-order))

(defn get-chapters [books]
  (mapcat (fn [[k v]]
         (let [i (intify v)]
           (map (fn [[n c]] [k, n, c]) i))) books))

(defn get-verses [verses]
  (mapcat (fn [[b c d]]
            (let [i (intify d)]
              (map (fn [[v t]] [b, c, v, t]) i))) verses))

(def parse (comp get-verses get-chapters get-books))

(defn -main
  [& args]
  (let [bible (parse-string (slurp "ESV.json"))]
    (first (parse bible))))

Haskell

{-# LANGUAGE OverloadedStrings #-}
module Main where

import           Control.Lens
import           Data.Aeson
import           Data.Aeson.Lens
import qualified Data.ByteString.Lazy.Char8 as BS
import           Data.List                  (elemIndex, sortOn)
import qualified Data.Text                  as T

bookOrder = ["Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy",
    "Joshua", "Judges", "Ruth", "1 Samuel", "2 Samuel", "1 Kings", "2 Kings",
    "1 Chronicles", "2 Chronicles", "Ezra", "Nehemiah", "Esther", "Job",
    "Psalms", "Proverbs", "Ecclesiastes", "Song of Solomon", "Isaiah",
    "Jeremiah", "Lamentations", "Ezekiel", "Daniel", "Hosea", "Joel", "Amos",
    "Obadiah", "Jonah", "Micah", "Nahum", "Habakkuk", "Zephaniah", "Haggai",
    "Zechariah", "Malachi", "Matthew", "Mark", "Luke", "John", "Acts",
    "Romans", "1 Corinthians", "2 Corinthians", "Galatians", "Ephesians",
    "Philippians", "Colossians", "1 Thessalonians", "2 Thessalonians",
    "1 Timothy", "2 Timothy", "Titus", "Philemon", "Hebrews", "James",
    "1 Peter", "2 Peter", "1 John", "2 John", "3 John", "Jude", "Revelation"]

main = do
    Just obj <- decode <$> BS.readFile "ESV.json" :: IO (Maybe Value)
    let bible = parseBible obj
    print bible

parseBible obj =
    (do (book, obj) <- obj ^@.. members
        (chapter, obj) <- obj ^@.. members
        (verse, String text) <- obj ^@.. members
        return (book, readText chapter :: Int, readText verse :: Int, text))
    & sortOn sortKey
  where
    readText = read . T.unpack
    sortKey (book, chapter, verse, _) = (elemIndex book bookOrder, chapter, verse)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment