// src/state/DragSubject.ts

export class DragSubject {
  private type: Type;
  private mouseOffset?: Vec;

  static None(): DragSubject {
    const out = new DragSubject();
    out.type = Type.None;
    return out;
  }

  static Ball(mouseOffset: Vec): DragSubject {
    const out = new DragSubject();
    out.type = Type.Ball;
    out.mouseOffset = mouseOffset;
    return out;
  }

  match<A>(handlers: MatchHandlers<A>): A {
    switch (this.type) {
      case Type.None:
        return handlers.none();
      case Type.Ball:
        return handlers.ball(this.mouseOffset as Vec);
    }
  }
}

enum Type {
  None = 'None',
  Ball = 'Ball',
}

interface MatchHandlers<A> {
  none: () => A;
  ball: (mouseOffset: Vec) => A;
}
    

module Quux.MyModule (map) where

import qualified Quux.Shoo as S hiding (map)

-- Mapping over lists
map :: (a -> b) -> [a] -> [b]
map _ []     = []
map f (x:xs) = f x : map f xs

class Monoid a where
  empty :: a

  (<>) :: a -> a -> a

-- Some strings
-- several comments
s1 :: String
s1 = "\"this is a test\""

n1 :: Int
n1 = 4212.3

case x of
  Just x -> x
  Nothing -> error "This is a message"
    

#lang racket

;; Some racket code
(define (fact n)
  (if (zero? n)
      1
      (* n (fact (- n 1)))))

;; Even and odd
(define (even? n)
  (if (zero? n)
      #t
      (odd? (- n 1))))

(define (odd? n)
  (if (zero? n)
      #f
      (even? (- n 1))))

"a string to test"

(define (eval e r)
  (match e
    [(? number?) e]
    [(? symbol?) (r e)]
    [`(if ,a ,b ,c)
     (let ([v (eval a r)])
       (eval (if v b c) r))]
    [else (error (format "Unrecognized expression: ~a" e))]))