sound-change-0.1.0.0: Apply sound changes to words
Copyright(c) Owen Bechtel 2023
LicenseMIT
Maintainerombspring@gmail.com
Stabilityexperimental
Safe HaskellSafe-Inferred
LanguageHaskell2010

Language.Change.Quote

Description

 
Synopsis

Documentation

ch :: QuasiQuoter Source #

Compile a sound change specification into a value of type Change Char.

Example:

setV = "aeiou"

change1 = [ch|
  m, n, ŋ > { m / _{mpb}; n / _{ntd}; ŋ / _{ŋkg} }
  { p > b; t > d; k > g } / V_V
  |]

The sound change in this example consists of two statements separated by a newline. The first statement says "m, n, and ŋ become /m/ when followed by m, p, or b, /n/ when followed by n, t, or d, and /ŋ/ when followed by ŋ, k, or g." The second statement says that voiceless stops (p, t, and k) become voiced when between two vowels. The uppercase V here is shorthand for "any element of setV."

All uppercase letters are interpreted in this way, which means they are not allowed as phonemes. Whitespace characters, as well as the following symbols ( ,>/;{}[]%_!?* ) are also not allowed as phonemes. All other unicode characters are allowed. (For example, you can use # as a "phoneme" representing the start or end of a word.)

Here's another example:

change2 = [ch|
  V > % / s_{ptk}             // vowel loss after /s/ before stops
  { o > ø; u > y } / _V!*{ji} // umlaut before /j/ and /i/ (with optional consonants in between) 
  y > i / _                   // unconditional shift
 |]

This example illustrates several features:

  • You can create line comments with //.
  • The left side of > need not be a single phoneme; it can also be a set of phonemes (in this case V).
  • The symbol % represents the empty string.
  • Certain suffixes can be added to phonemes and phoneme-sets to create more complex patterns:

    • X! matches anything not in the set X.
    • X* matches zero or more elements of X.
    • X? matches zero or one elements of X.
    • There are also the combinations X!* and X!?.
  • To create an unconditional sound change, use the empty environment _.
  • The statements in a sound change are applied in a single traversal. This means that the same phoneme cannot be affected by more than one statement. For example, the change above would convert "yni" into "ini," and "uni" into "yni." (If you want to sequence multiple changes, use chs.)
  • If multiple statements are applicable to the same phoneme, the first one is applied. For example, the change above would convert "soki" into "ski", not "søki."

Other noteworthy things:

  • As mentioned above, capital letters refer to sets of characters: V refers to setV, N refers to setN, and so on. To refer to sets with longer names, you can use square brackets; for example, if you define setNasal :: [Char], you can refer to it with [Nasal].
  • It is possible to have multiple conditions in a single statement. For example, e > i / _a, a_ means "/e/ becomes /i/ when before /a/ or after /a/."
  • The parser is whitespace-sensitive. Horizontal space characters can go almost anywhere, but newlines are only allowed between statements (where they are required) and inside of {} blocks.

chs :: QuasiQuoter Source #

Compile a sequence of sound changes into a value of type [Change Char]. Each change is preceded by a bullet *. For example:

changes = [chs|
  * p > f / _{tk}
    t > θ / _{pk}
    k > x / _{pt} // these three statements are applied in a single traversal
  * x > ç / i_    // this statement is applied after the ones before it
  * i > j / _V
  |]

For example, applyChanges changes "ikt" would return "içt".