   """
   "(first (concat {{1} {2} {3}}))", 1
 
+  'mixing constructor classes with fundeps'
+  """
+  Mappable (class [wrapper]
+    map (fn [what onto]
+      (: (Fn (Fn a b) (wrapper a) (wrapper b)))
+      (# Apply what to every value inside onto .)))
+
+  Bag (class [bag item]
+    size (fn [bag]
+      (: (Fn bag Num))
+      (# The number of items in the bag .))
+
+    empty (: bag)
+
+    fold (fn [with initial over]
+      (: (Fn (Fn item a a) a bag a))
+      (# Fold over with using initial ...))
+
+    join (fn [what with]
+      (: (Fn bag bag bag))
+      (# Fold over with using initial ...)))
+
+  array-mappable (instance (Mappable Array)
+    map (macro [what over]
+      (: (Fn (Fn a b) (Array a) (Array b)))
+      (Js.method over "map" {what})))
+
+  array-bag (instance (Bag (Array a) a)
+    size (macro [list]
+      (: (Fn (List a) Num))
+      (Js.access list "size"))
+
+    empty {}
+
+    fold (macro [with initial list]
+      (: (Fn (Fn a b b) b (Array a) b))
+      (Js.method list "reduce"
+        {(fn [acc x] (with x acc)) initial}))
+
+    join (macro [what with]
+      (: (Fn (Array a) (Array a) (Array a)))
+      (Js.method what "concat" {with})))
+
+  concat (fn [bag-of-bags]
+    (fold join empty bag-of-bags))
+
+  concat-map (fn [what over]
+    (concat (map what over)))
+
+  """
+  "(size (concat-map (fn [x] {}) {1 2 3}))", 0
+
   # The following doesn't work because the Collection type class specifies
   # that the constructor takes only one argument.
   #

  assignCompileAs ctx, expression, translatedExpression, yes

patternCompile = (ctx, pattern, matched, polymorphic) ->

  # caching can occur while compiling the pattern
  # precs are {cond}s and {cache}s, sorted in order they need to be executed
  {precs, assigns} = expressionCompile ctx, pattern

    else if type.TypeConstr
      no
    else if type.TypeApp
      isNormalizedConstraintArgument type.op


typeEq = (a, b) ->
