I think the mutable solution is acceptable but there may be a better one. Why not play with some design ideas and see what works?

There are some options for "tying the knot" (cf. http://www.haskell.org/haskellwiki/Tying_the_Knot), e.g.:

    trait Table {
      protected def getFKs: List[FK]
      lazy val foreignKeys = getFKs(this)
    }
    lazy val tables: List[Table] = mTables.map { mt => new Table {
      def getFKs = ... // look up in the tables list here
    }}
    tables.foreach(_.foreignKeys) // force initialization

What effect would this have on the API? Users of Slick may want to create schema models, too. Is this easier or harder to use than a mutable API? Can we have a basic read-only API that allows mutable and immutable implementations? (And if we can, is it worth the extra effort to provide both?)