;; Operator sections and list comprehensions.

;; ── Operator references (unchanged expr shape) ──
(hk-test
  "op as value (+)"
  (hk-parse "(+)")
  (list :var "+"))

(hk-test
  "op as value (-)"
  (hk-parse "(-)")
  (list :var "-"))

(hk-test
  "op as value (:)"
  (hk-parse "(:)")
  (list :var ":"))

(hk-test
  "backtick op as value"
  (hk-parse "(`div`)")
  (list :var "div"))

;; ── Right sections (op expr) ──
(hk-test
  "right section (+ 5)"
  (hk-parse "(+ 5)")
  (list :sect-right "+" (list :int 5)))

(hk-test
  "right section (* x)"
  (hk-parse "(* x)")
  (list :sect-right "*" (list :var "x")))

(hk-test
  "right section with backtick op"
  (hk-parse "(`div` 2)")
  (list :sect-right "div" (list :int 2)))

;; `-` is unary in expr position — (- 5) is negation, not a right section
(hk-test
  "(- 5) is negation, not a section"
  (hk-parse "(- 5)")
  (list :neg (list :int 5)))

;; ── Left sections (expr op) ──
(hk-test
  "left section (5 +)"
  (hk-parse "(5 +)")
  (list :sect-left "+" (list :int 5)))

(hk-test
  "left section with backtick"
  (hk-parse "(x `mod`)")
  (list :sect-left "mod" (list :var "x")))

(hk-test
  "left section with cons (x :)"
  (hk-parse "(x :)")
  (list :sect-left ":" (list :var "x")))

;; ── Mixed / nesting ──
(hk-test
  "map (+ 1) xs"
  (hk-parse "map (+ 1) xs")
  (list
    :app
    (list
      :app
      (list :var "map")
      (list :sect-right "+" (list :int 1)))
    (list :var "xs")))

(hk-test
  "filter (< 0) xs"
  (hk-parse "filter (< 0) xs")
  (list
    :app
    (list
      :app
      (list :var "filter")
      (list :sect-right "<" (list :int 0)))
    (list :var "xs")))

;; ── Plain parens and tuples still work ──
(hk-test
  "plain parens unwrap"
  (hk-parse "(1 + 2)")
  (list :op "+" (list :int 1) (list :int 2)))

(hk-test
  "tuple still parses"
  (hk-parse "(a, b, c)")
  (list
    :tuple
    (list (list :var "a") (list :var "b") (list :var "c"))))

;; ── List comprehensions ──
(hk-test
  "simple list comprehension"
  (hk-parse "[x | x <- xs]")
  (list
    :list-comp
    (list :var "x")
    (list
      (list :q-gen (list :p-var "x") (list :var "xs")))))

(hk-test
  "comprehension with filter"
  (hk-parse "[x * 2 | x <- xs, x > 0]")
  (list
    :list-comp
    (list :op "*" (list :var "x") (list :int 2))
    (list
      (list :q-gen (list :p-var "x") (list :var "xs"))
      (list
        :q-guard
        (list :op ">" (list :var "x") (list :int 0))))))

(hk-test
  "comprehension with let"
  (hk-parse "[y | x <- xs, let y = x + 1]")
  (list
    :list-comp
    (list :var "y")
    (list
      (list :q-gen (list :p-var "x") (list :var "xs"))
      (list
        :q-let
        (list
          (list
            :bind
            (list :p-var "y")
            (list :op "+" (list :var "x") (list :int 1))))))))

(hk-test
  "nested generators"
  (hk-parse "[(x, y) | x <- xs, y <- ys]")
  (list
    :list-comp
    (list :tuple (list (list :var "x") (list :var "y")))
    (list
      (list :q-gen (list :p-var "x") (list :var "xs"))
      (list :q-gen (list :p-var "y") (list :var "ys")))))

(hk-test
  "comprehension with constructor pattern"
  (hk-parse "[v | Just v <- xs]")
  (list
    :list-comp
    (list :var "v")
    (list
      (list
        :q-gen
        (list :p-con "Just" (list (list :p-var "v")))
        (list :var "xs")))))

(hk-test
  "comprehension with tuple pattern"
  (hk-parse "[x + y | (x, y) <- pairs]")
  (list
    :list-comp
    (list :op "+" (list :var "x") (list :var "y"))
    (list
      (list
        :q-gen
        (list
          :p-tuple
          (list (list :p-var "x") (list :p-var "y")))
        (list :var "pairs")))))

(hk-test
  "combination: generator, let, guard"
  (hk-parse "[z | x <- xs, let z = x * 2, z > 10]")
  (list
    :list-comp
    (list :var "z")
    (list
      (list :q-gen (list :p-var "x") (list :var "xs"))
      (list
        :q-let
        (list
          (list
            :bind
            (list :p-var "z")
            (list :op "*" (list :var "x") (list :int 2)))))
      (list
        :q-guard
        (list :op ">" (list :var "z") (list :int 10))))))

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