;; wordcount.hs — word and line counting via string splitting.

(define
  hk-prog-val
  (fn
    (src name)
    (hk-deep-force (get (hk-eval-program (hk-core src)) name))))

(define
  hk-as-list
  (fn
    (xs)
    (cond
      ((and (list? xs) (= (first xs) "[]")) (list))
      ((and (list? xs) (= (first xs) ":"))
        (cons (nth xs 1) (hk-as-list (nth xs 2))))
      (:else xs))))

(define
  hk-wc-src
  "wordCount s = length (words s)\nlineCount s = length (lines s)\ncharCount = length\n\nlongestWord s = foldl longer \"\" (words s)\n  where longer a b = if length a >= length b then a else b\n\nshortestWord s = foldl shorter (head (words s)) (words s)\n  where shorter a b = if length a <= length b then a else b\n\nuniqueWords s = nub (words s)\n")

(hk-test
  "wordCount single word"
  (hk-prog-val (str hk-wc-src "r = wordCount \"hello\"\n") "r")
  1)

(hk-test
  "wordCount two words"
  (hk-prog-val (str hk-wc-src "r = wordCount \"hello world\"\n") "r")
  2)

(hk-test
  "wordCount with extra spaces"
  (hk-prog-val (str hk-wc-src "r = wordCount \"  foo  bar  \"\n") "r")
  2)

(hk-test
  "wordCount empty = 0"
  (hk-prog-val (str hk-wc-src "r = wordCount \"\"\n") "r")
  0)

(hk-test
  "lineCount one line"
  (hk-prog-val (str hk-wc-src "r = lineCount \"hello\"\n") "r")
  1)

(hk-test
  "lineCount two lines"
  (hk-prog-val (str hk-wc-src "r = lineCount \"a\\nb\"\n") "r")
  2)

(hk-test
  "charCount \"hello\" = 5"
  (hk-prog-val (str hk-wc-src "r = charCount \"hello\"\n") "r")
  5)

(hk-test
  "charCount empty = 0"
  (hk-prog-val (str hk-wc-src "r = charCount \"\"\n") "r")
  0)

(hk-test
  "longestWord picks longest"
  (hk-prog-val (str hk-wc-src "r = longestWord \"a bb ccc\"\n") "r")
  "ccc")

(hk-test
  "uniqueWords removes duplicates"
  (hk-as-list
    (hk-prog-val (str hk-wc-src "r = uniqueWords \"a b a c b\"\n") "r"))
  (list "a" "b" "c"))

{:fails hk-test-fails :pass hk-test-pass :fail hk-test-fail}
