Solution (source code)

= Solution

Use relative character frequencies, an <empirical distribution>. A nonempty <string> is required because an empty sample has no normalized frequency distribution:
``
class DistFromString(s: String) extends FiniteDist[Char] {
  require(s != null && s.nonEmpty, "A nonempty string is required")
  private val chars = s.toList
  private val domain = chars.distinct

  def getDom: List[Char] = domain

  def getProb(c: Char): Double =
    chars.count(_ == c).toDouble / s.length.toDouble
}
``
`distinct` removes repeated support entries without changing which characters occur. Every returned domain element has positive frequency, and every absent character has frequency zero. The occurrence counts partition the <string>'s character positions, so their total is `s.length`, establishing normalization. \b[For `Scala`, the masses are $2/5$ for `a` and $1/5$ each for `S`, `c` and `l`.] The character units here are exactly the `Char` values supplied by `s.toList`; the interface does not specify a different notion of displayed text characters. The code has no explicit loop beyond the specified library traversals.