-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | An Enigma machine simulator with display.
--   
--   The crypto-enigma package is an Enigma machine simulator with rich
--   display and machine state details.
--   
--   Currently support is only provided for the machine models in most
--   widespread general use during the war years: the I, M3, and M4.
--   
--   For basic functionality, including some introspection of machine state
--   and the mappings performed, simply
--   
--   <pre>
--   &gt; import Crypto.Enigma
--   </pre>
--   
--   For richer display functionality additionally
--   
--   <pre>
--   &gt; import Crypto.Enigma.Display
--   </pre>
--   
--   (Note that this package assumes support for combining Unicode, without
--   which some output may appear garbled.)
@package crypto-enigma
@version 0.1.1.5


-- | An Enigma machine simulator with rudimentary display, currently
--   limited to the I, M3, and M4 models.
--   
--   Richer display is provided by <a>Crypto.Enigma.Display</a>.
module Crypto.Enigma

-- | A component used to construct an Enigma machine (embodied in an
--   <a>EnigmaConfig</a>) identified by its <a>name</a>, and characterized
--   by its physical <a>wiring</a> and additionally — for rotors other than
--   the reflector — by <a>turnovers</a> which govern the <a>step</a>ping
--   of the machine in which it is installed.
data Component

-- | The component's <a>Name</a>.
name :: Component -> Name

-- | The component's <a>Wiring</a>.
wiring :: Component -> Wiring

-- | The component's <a>Turnovers</a>.
turnovers :: Component -> Turnovers

-- | A string identifying a <a>Component</a> of an Enigma machine. For
--   rotors (including the reflector) this is one of the conventional
--   letter or Roman numeral designations (e.g., <tt>"IV"</tt> or
--   <tt>"β"</tt>). For the plugboard this is the conventional string of
--   letter pairs (separated by periods), indicating letters wired together
--   by plugging (e.g., <tt>"AU.ZM.ZL.RQ"</tt>). Absence or non-use of a
--   plugboard can be indicated with a lone "~". See <a>name</a>.
type Name = String

-- | The <a>Mapping</a> established by the physical wiring of a
--   <a>Component</a>, when 01 is at the window position for rotors, and by
--   the plug arrangement for the plugboard. See <a>wiring</a>.
type Wiring = Mapping

-- | The list of letters on the rotor's ring that appear at the window when
--   a <tt>Component'</tt>s ring is in the turnover position. Not
--   applicable (and empty) for the plugboard and for reflectors. See
--   <a>turnovers</a>.
type Turnovers = String

-- | The <a>Component</a> with the specified <a>Name</a>.
component :: Name -> Component

-- | The list of valid <a>Component</a> <a>Name</a>s for rotors.
rotors :: [Name]

-- | The list of valid <a>Component</a> <a>Name</a>s for reflectors.
reflectors :: [Name]

-- | The complete description of the state of an Enigma machine, consisting
--   of <a>components</a>, <a>positions</a>, and <a>rings</a>.
--   
--   Two functions (<a>configEnigma'</a> and <a>configEnigma</a>) are
--   provided for creating <a>EnigmaConfig</a>, which differ in their
--   handling of errors in the provided arguments specifying the
--   configuration (the only potential source of errors, since all other
--   arguments throught the package are coerced to valid values).
data EnigmaConfig

-- | Create an <a>EnigmaConfig</a> from a conventional specification.
--   
--   A (safe public, <a>"smart"</a>, total) constructor intended for use in
--   pure code that does validation and takes a conventional specification
--   as input, in the form of four strings:
--   
--   <ul>
--   <li>The rotor <a>Name</a>s, separated by dashes (e.g.
--   <tt>"C-V-I-II"</tt>); see <a>Name</a>.</li>
--   <li>The letters visible at the windows (e.g. <tt>"MQR"</tt>); see
--   <a>windows</a>.</li>
--   <li>The plugboard specification (which may be omitted with
--   <tt>"~"</tt>); see <a>Name</a>.</li>
--   <li>The position of the letter ring on each rotor, separated by
--   periods (e.g. <tt>"22.11.16"</tt>); see <a>rings</a>.</li>
--   </ul>
--   
--   Following convention, the elements of these strings are in physical
--   machine order as the operator sees them, which is the reverse of the
--   order in which they are encountered in processing (see <a>stages</a>).
--   
--   Validation is permissive, allowing for ahistorical collections and
--   numbers of rotors (including reflectors at the rotor stage, and
--   trivial degenerate machines; e.g., <tt>configEnigma "-" "A" ""
--   "01"</tt>), and any number of (non-contradictory) plugboard wirings
--   (including none). Invalid arguments return an <a>EnigmaError</a>:
--   
--   <pre>
--   &gt;&gt;&gt; configEnigma' "c-β-V-III-II" "LQVI" "AM.EU.ZiL" "16.01.21.11"
--   Left Bad plugboard: AM.EU.ZiL
--   </pre>
configEnigma' :: String -> String -> String -> String -> Either EnigmaError EnigmaConfig

-- | Create an <a>EnigmaConfig</a> from a conventional specification.
--   
--   A thin convenience wrapper on <tt>configEnigma'</tt> intended for most
--   uses (e.g., interactive) that takes the same arguments but errors with
--   an informative message and a stack trace:
--   
--   <pre>
--   &gt;&gt;&gt; configEnigma "c-β-V-III-II" "LQVI" "AM.EU.ZiL" "16.01.21.11"
--   *** Exception: Bad plugboard: AM.EU.ZiL
--   CallStack (from HasCallStack):
--     error, called at crypto-enigma/Crypto/Enigma.hs:317:21 in main:Crypto.Enigma
--   </pre>
--   
--   This should be used instead of <tt>read</tt>, which cannot report
--   error details:
--   
--   <pre>
--   &gt;&gt;&gt; read "c-β-V-III-II LQVI AM.EU.ZiL 16.01.21.11" :: EnigmaConfig
--   *** Exception: Prelude.read: no parse
--   </pre>
configEnigma :: String -> String -> String -> String -> EnigmaConfig

-- | The sequential, (forward) processing-order, <a>Stage</a> occupied by
--   each <a>Component</a> in an <a>EnigmaConfig</a>, starting with
--   <tt>0</tt> for the plugboard and ending with the reflector.
--   
--   <pre>
--   &gt;&gt;&gt; stages $ configEnigma "c-β-V-III-II" "LQVI" "AM.EU.ZL" "16.01.21.11"
--   [0,1,2,3,4,5]
--   </pre>
--   
--   <pre>
--   components cfg == ((components cfg !!) &lt;$&gt; stages cfg)
--   </pre>
--   
--   The term 'stage' (lowercase) is also used here to encompass subsequent
--   reverse processing order stages (see, for example,
--   <a>stageMappingList</a>).
stages :: EnigmaConfig -> [Stage]

-- | The <a>Name</a> of each <a>Component</a> in an <a>EnigmaConfig</a>, in
--   processing order. Unchanged by <a>step</a>.
--   
--   <pre>
--   &gt;&gt;&gt; components $ configEnigma "c-β-V-III-II" "LQVI" "AM.EU.ZL" "16.01.21.11"
--   ["AM.EU.ZL","II","III","V","\946","c"]
--   </pre>
--   
--   (Note that any Unicode characters are <a>stored by Haskell</a> as
--   their Unicode value: here <tt>"\946" == "β"</tt>.)
components :: EnigmaConfig -> [Name]

-- | The <a>Position</a> of each <a>Component</a> in an
--   <a>EnigmaConfig</a>, in machine processing order. May be changed by
--   <a>step</a>.
--   
--   <pre>
--   &gt;&gt;&gt; positions $ configEnigma "c-β-V-III-II" "LQVI" "AM.EU.ZL" "16.01.21.11"
--   [1,25,2,17,23,1]
--   </pre>
--   
--   For plugboard and reflector, this will always be <tt>1</tt> since the
--   former cannot rotate, and the latter does not (neither will be changed
--   by <a>step</a>):
--   
--   <pre>
--   head (positions cfg) == 1
--   </pre>
--   
--   <pre>
--   last (positions cfg) == 1
--   </pre>
--   
--   This determines the encoding performed by a component (see
--   <a>componentMapping</a>).
positions :: EnigmaConfig -> [Position]

-- | The location of ring letter <tt>A</tt> on the rotor for each
--   <a>Component</a> in an <a>EnigmaConfig</a>, in machine processing
--   order. Unchanged by <a>step</a>.
--   
--   <pre>
--   &gt;&gt;&gt; rings $ configEnigma "c-β-V-III-II" "LQVI" "AM.EU.ZL" "16.01.21.11"
--   [1,11,21,1,16,1]
--   </pre>
--   
--   For plugboard and reflector, this will always be <tt>1</tt> since the
--   former lacks a ring, and for latter ring position is irrelevant (the
--   letter ring is not visible, and has no effect on when turnovers
--   occur):
--   
--   <pre>
--   head (rings cfg) == 1
--   </pre>
--   
--   <pre>
--   last (rings cfg) == 1
--   </pre>
rings :: EnigmaConfig -> [Int]

-- | The letters at the window in an <a>EnigmaConfig</a>, in physical,
--   conventional order. This is the (only) visible manifestation of
--   configuration changes during operation.
--   
--   <pre>
--   &gt;&gt;&gt; windows $ configEnigma "c-β-V-III-II" "LQVI" "AM.EU.ZL" "16.01.21.11"
--   "LQVI"
--   </pre>
windows :: EnigmaConfig -> String

-- | The generalized rotational position of a <a>Component</a>. For rotors,
--   this is denoted by number on the rotor (not letter ring) that is at
--   the "window position". For other components the only meaningful
--   position is <tt>1</tt> (see <a>positions</a>).
--   
--   This (alone) determines the permutations applied to the component's
--   <a>Wiring</a> to produce its current <a>Mapping</a> (see
--   <a>componentMapping</a>).
type Position = Int

-- | The (zero-based) index of the processing stage occupied by a
--   <a>Component</a> in an <tt>EngmaConfig</tt>. See <a>stages</a>.
type Stage = Int

-- | Step the machine to a new <a>EnigmaConfig</a> by rotating the
--   rightmost (first) rotor one position, and other rotors as determined
--   by the <a>positions</a> of rotors in the machine. In the physical
--   machine, a step occurs in response to each operator keypress, prior to
--   processing that key's letter. (See <a>enigmaEncoding</a>.)
--   
--   Stepping leaves the <a>components</a>, <a>stages</a> and <a>rings</a>
--   of a configuration unchanged, changing only <a>positions</a>, which is
--   manifest in changes of the letters at the <a>windows</a>:
--   
--   <pre>
--   &gt;&gt;&gt; let cfg = configEnigma "c-γ-V-I-II" "LXZO" "UX.MO.KZ.AY.EF.PL" "03.17.04.01"
--   
--   &gt;&gt;&gt; putStr $ unlines $ show &lt;$&gt; take 5 (iterate step cfg)
--   c-γ-V-I-II LXZO UX.MO.KZ.AY.EF.PL 03.17.04.01
--   c-γ-V-I-II LXZP UX.MO.KZ.AY.EF.PL 03.17.04.01
--   c-γ-V-I-II LXZQ UX.MO.KZ.AY.EF.PL 03.17.04.01
--   c-γ-V-I-II LXZR UX.MO.KZ.AY.EF.PL 03.17.04.01
--   c-γ-V-I-II LXZS UX.MO.KZ.AY.EF.PL 03.17.04.01
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let cfg = configEnigma "c-γ-V-I-II" "LXZO" "UX.MO.KZ.AY.EF.PL" "03.17.04.01"
--   
--   &gt;&gt;&gt; take 5 $ map windows $ iterate step cfg
--   ["LXZO","LXZP","LXZQ","LXZR","LXZS"]
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; let cfg = configEnigma "c-γ-V-I-II" "LXZO" "UX.MO.KZ.AY.EF.PL" "03.17.04.01"
--   
--   &gt;&gt;&gt; take 5 $ map positions $ iterate step cfg
--   [[1,15,23,8,10,1],[1,16,23,8,10,1],[1,17,23,8,10,1],[1,18,23,8,10,1],[1,19,23,8,10,1]]
--   </pre>
step :: EnigmaConfig -> EnigmaConfig

-- | The mapping used by a component (see <a>wiring</a> and
--   <a>componentMapping</a>) or by the machine (see <a>enigmaMapping</a>)
--   to perform a <a>simple substitution encoding</a>.
--   
--   This is expressed as a string of letters indicating the mapped-to
--   letter for the letter at that position in the alphabet — i.e., as a
--   permutation of the alphabet. For example, the mapping
--   <tt>EKMFLGDQVZNTOWYHXUSPAIBRCJ</tt> encodes <tt>A</tt> to <tt>E</tt>,
--   <tt>B</tt> to <tt>K</tt>, <tt>C</tt> to <tt>M</tt>, ... <tt>Y</tt> to
--   <tt>C</tt>, and <tt>Z</tt> to <tt>J</tt>.
type Mapping = String

-- | The direction that a signal flows through a <a>Component</a>. During
--   encoding of a character, the signal passes first through the wiring of
--   each component, from right to left in the machine, in a forward
--   (<a>Fwd</a>) direction, then through the reflector, and then, from
--   left to right, through each component again, in reverse (<a>Rev</a>).
--   
--   This direction affects the encoding performed by the component (see
--   <a>componentMapping</a>).
data Direction
Fwd :: Direction
Rev :: Direction

-- | The <a>Mapping</a> performed by a <a>Component</a> as a function of
--   its <a>Position</a> and the <a>Direction</a> of the signal passing
--   through it.
--   
--   The base encoding of a <a>Component</a>, performed with rotor position
--   <tt>1</tt> at the window, is set by its <a>wiring</a>.
--   
--   <pre>
--   componentMapping Fwd comp 1 == wiring comp
--   </pre>
--   
--   For all other positions, the encoding is a cyclic permutation this
--   mapping's inputs (backward) and outputs (forward) by the rotational
--   offset of the rotor away from the <tt>1</tt> position (though in an
--   actual <tt>EmigmaConfig</tt> such positions occur only for rotors; see
--   <a>positions</a>).
--   
--   Note that because the wiring of reflectors generates mappings that
--   consist entirely of paired exchanges of letters, reflectors (at any
--   position) produce the same mapping in both directions (the same is
--   true of the plugboard):
--   
--   <pre>
--   &gt;&gt;&gt; let tst c n = componentMapping Fwd (component c) n == componentMapping Rev (component c) n
--   
--   &gt;&gt;&gt; and $ tst &lt;$&gt; ["A","B","C","b","c"] &lt;*&gt; [1..26]
--   True
--   </pre>
componentMapping :: Direction -> Component -> Position -> Mapping

-- | The list of <a>Mapping</a>s for each stage of an <a>EnigmaConfig</a>:
--   the encoding performed by the <a>Component</a> <i>at that point</i> in
--   the progress through the machine.
--   
--   These are arranged in processing order, beginning with the encoding
--   performed by the plugboard, followed by the forward encoding performed
--   by each rotor (see <a>componentMapping</a>), then the reflector,
--   followed by the reverse encodings by each rotor, and finally by the
--   plugboard again.
--   
--   <pre>
--   &gt;&gt;&gt; putStr $ unlines $ stageMappingList (configEnigma "b-γ-V-VIII-II" "LFAQ" "UX.MO.KZ.AY.EF.PL" "03.17.04.11")
--   YBCDFEGHIJZPONMLQRSTXVWUAK
--   LORVFBQNGWKATHJSZPIYUDXEMC
--   BJYINTKWOARFEMVSGCUDPHZQLX
--   ILHXUBZQPNVGKMCRTEJFADOYSW
--   YDSKZPTNCHGQOMXAUWJFBRELVI
--   ENKQAUYWJICOPBLMDXZVFTHRGS
--   PUIBWTKJZSDXNHMFLVCGQYROAE
--   UFOVRTLCASMBNJWIHPYQEKZDXG
--   JARTMLQVDBGYNEIUXKPFSOHZCW
--   LFZVXEINSOKAYHBRGCPMUDJWTQ
--   YBCDFEGHIJZPONMLQRSTXVWUAK
--   </pre>
--   
--   Note that, because plugboard <a>Mapping</a> is established by paired
--   exchanges of letters (see <a>componentMapping</a>),
--   
--   <pre>
--   head (stageMappingList cfg) == last (stageMappingList cfg)
--   </pre>
--   
--   As noted (see <a>stages</a>) the term 'stage' here encompasses reverse
--   processing:
--   
--   <pre>
--   length (stageMappingList cfg) == 2 * length (stages cfg) - 1
--   </pre>
--   
--   A richer example of how this list is used, and how it can be
--   interpreted, can be found in
--   <a>Crypto.Enigma.Display#displayEnigmaConfigInternalEG</a>.
stageMappingList :: EnigmaConfig -> [Mapping]

-- | The list of <a>Mapping</a>s an <a>EnigmaConfig</a> has performed by
--   each stage: the encoding performed by the <a>EnigmaConfig</a> <i>up to
--   that point</i> in the progress through the machine.
--   
--   <pre>
--   &gt;&gt;&gt; putStr $ unlines $ enigmaMappingList (configEnigma "b-γ-V-VIII-II" "LFAQ" "UX.MO.KZ.AY.EF.PL" "03.17.04.11")
--   YBCDFEGHIJZPONMLQRSTXVWUAK
--   MORVBFQNGWCSJHTAZPIYEDXULK
--   EVCHJTGMKZYUAWDBXSOLNIQPFR
--   UDHQNFZKVWSAIOXLYJCGMPTRBE
--   BKNUMPIGREJYCXLQVHSTOAFWDZ
--   NCBFPMJYXAIGKRODTWZVLEUHQS
--   HIUTFNSAOPZKDVMBGREYXWQJLC
--   CAEQTJYUWIGMVKNFLPRXDZHSBO
--   RJMXFBCSHDQNOGELYUKZTWVPAI
--   COYWEFZPNVGHBIXATUKQMJDRLS
--   CMAWFEKLNVGHBIUYTXZQOJDRPS
--   </pre>
--   
--   Since these may be thought of as cumulative encodings,
--   
--   <pre>
--   enigmaMapping cfg == last (enigmaMappingList cfg)
--   </pre>
enigmaMappingList :: EnigmaConfig -> [Mapping]

-- | The <a>Mapping</a> performed by the Enigma machine.
--   
--   <pre>
--   &gt;&gt;&gt; enigmaMapping (configEnigma "b-γ-V-VIII-II" "LFAQ" "UX.MO.KZ.AY.EF.PL" "03.17.04.11")
--   "CMAWFEKLNVGHBIUYTXZQOJDRPS"
--   </pre>
--   
--   A example of a richer display of this information can be found in
--   <a>Crypto.Enigma.Display#displayEnigmaSingleEG</a>.
enigmaMapping :: EnigmaConfig -> Mapping

-- | A (<a>synonym</a> for) <a>String</a>, indicating that <a>message</a>
--   will be applied to the corresponding argument.
type Message = String

-- | Convert a <a>String</a> to valid Enigma machine input: replace any
--   symbols for which there are standard Kriegsmarine substitutions,
--   remove any remaining non-letter characters, and convert to uppercase.
--   This function is applied automatically to <a>String</a>s suppied as
--   <a>Message</a> arguments to functions in this package.
message :: String -> Message

-- | Encode a <a>Message</a> using a given (starting) machine
--   configuration, by <a>step</a>ping the configuration prior to
--   processing each character of the message. This produces a new
--   configuration (with new <a>positions</a> only) for encoding each
--   character, which serves as the "starting" configuration for subsequent
--   processing of the message.
--   
--   <pre>
--   &gt;&gt;&gt; enigmaEncoding (configEnigma "b-γ-V-VIII-II" "LFAP" "UX.MO.KZ.AY.EF.PL" "03.17.04.11") "KRIEG"
--   "GOWNW"
--   </pre>
--   
--   The details of this encoding and its relationship to stepping from one
--   configuration to another are illustrated in
--   <a>Crypto.Enigma.Display#displayEnigmaOperationEG</a>.
--   
--   Note that because of the way the Enigma machine is designed, it is
--   always the case (provided that <tt>msg</tt> is all uppercase letters)
--   that
--   
--   <pre>
--   enigmaEncoding cfg (enigmaEncoding cfg msg) == msg
--   </pre>
enigmaEncoding :: EnigmaConfig -> Message -> String
instance GHC.Classes.Eq Crypto.Enigma.EnigmaConfig
instance GHC.Show.Show Crypto.Enigma.Component
instance GHC.Show.Show Crypto.Enigma.EnigmaError
instance GHC.Read.Read Crypto.Enigma.EnigmaConfig
instance GHC.Show.Show Crypto.Enigma.EnigmaConfig


-- | A module for rich display of the state of and encoding performed by
--   Enigma machines defined in <a>Crypto.Enigma</a>.
module Crypto.Enigma.Display

-- | Options for <a>displayEnigmaConfig</a>, <a>displayEnigmaOperation</a>,
--   and <a>listEnigmaOperation</a>, created using <a>displayOpts</a>. All
--   fields are coerced to valid values by display functions.
data DisplayOpts

-- | Default <a>DisplayOpts</a> equivalent to
--   <tt>DisplayOpts{format="single",showencoding=False,markerspec="bars",...}</tt>.
--   See individual options below for defaults values. This is the sole
--   method for providing and setting options for display functions. E.g.
--   to supply specify a <a>format</a> of <tt>"windows"</tt> which shows
--   encoding (see <a>showencoding</a>) provide
--   
--   <pre>
--   displayOpts{format="windows",showencoding=True}
--   </pre>
--   
--   as the <tt>DisplayOpts</tt> argument to a display finction.
displayOpts :: DisplayOpts

-- | A <a>Format</a> specifying the format used to display
--   <a>EnigmaConfig</a> machine configuration(s) that should be one of
--   <tt>"single"</tt>, <tt>"internal"</tt>, <tt>"windows"</tt>,
--   <tt>"config"</tt>, and <tt>"encoding"</tt>:
--   
--   <ul>
--   <li><i><tt>"single"</tt></i> A summary of the Enigma machine
--   configuration as its encoding (see <a>Mapping</a>), the letters at the
--   windows (see <a>windows</a>), and the <a>Position</a>s of the rotors
--   (see <a>positions</a>).Any valid letter being encoded (see
--   <a>showencoding</a>) by the configuration is indicated as input, and
--   the encoding of the letter is marked (see <a>markerspec</a>).For
--   example, <pre>K &gt; CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS LFAQ 10 16 24
--   07</pre>shows the process of encoding of the letter
--   <b><tt>'K'</tt></b> to <b><tt>'G'</tt></b>.</li>
--   <li><i><tt>"internal"</tt></i> An expaned schematic of the
--   configuration showing the encoding (see <a>Mapping</a>) performed by
--   each stage (see <a>stageMappingList</a>), along with an indication of
--   the stage (rotor number, <tt>"P"</tt> for plugboard, or <tt>"R"</tt>
--   for reflector), window letter (see <a>windows</a>), <a>Position</a>
--   (see <a>positions</a>) and <a>Name</a>, followed by the encoding for
--   the machine as a whole, and preceded by a (trivial, no-op) keyboard
--   "encoding" for reference.Any valid letter being encoded (see
--   <a>showencoding</a>) by the configuration is indicated as input, and
--   its encoding at each stage is marked (see <a>markerspec</a>).For
--   example, <pre>K &gt; ABCDEFGHIJK̲̅LMNOPQRSTUVWXYZ P
--   YBCDFEGHIJZ̲̅PONMLQRSTXVWUAK UX.MO.KZ.AY.EF.PL 1
--   LORVFBQNGWKATHJSZPIYUDXEMC̲̅ Q 07 II 2 BJY̲̅INTKWOARFEMVSGCUDPHZQLX A
--   24 VIII 3 ILHXUBZQPNVGKMCRTEJFADOYS̲̅W F 16 V 4
--   YDSKZPTNCHGQOMXAUWJ̲̅FBRELVI L 10 γ R ENKQAUYWJI̲̅COPBLMDXZVFTHRGS b 4
--   PUIBWTKJZ̲̅SDXNHMFLVCGQYROAE γ 3 UFOVRTLCASMBNJWIHPYQEKZDXG̲̅ V 2
--   JARTMLQ̲̅VDBGYNEIUXKPFSOHZCW VIII 1 LFZVXEINSOKAYHBRG̲̅CPMUDJWTQ II P
--   YBCDFEG̲̅HIJZPONMLQRSTXVWUAK UX.MO.KZ.AY.EF.PL G &lt;
--   CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS </pre>shows the "internals" of the same
--   proccess as avove using the same machine configuration: the encoding
--   of the letter <b><tt>'K'</tt></b> to
--   <b><tt>'G'</tt></b>:<ul><li><b><tt>'K'</tt></b> is entered at the
--   keyboard, which is then</li><li>encoded by the plugboard
--   (<tt>'P'</tt>), which includes <tt>"KZ"</tt> in its specification (see
--   <a>Name</a>), to <b><tt>'Z'</tt></b>, which is then</li><li>encoded by
--   the first rotor (<tt>'1'</tt>), a <tt>"II"</tt> rotor in the
--   <tt>07</tt> position (and <tt>'Q'</tt> at the window), to
--   <b><tt>'C'</tt></b>, which is then</li><li>encoded by the second rotor
--   (<tt>'2'</tt>), a <tt>"VIII"</tt> rotor in the <tt>24</tt> position
--   (and <tt>'A'</tt> at the window), to <b><tt>'Y'</tt></b>, which is
--   then</li><li>encoded by the third rotor (<tt>'3'</tt>), a <tt>"V"</tt>
--   rotor in the <tt>16</tt> position (and <tt>'F'</tt> at the window), to
--   <b><tt>'S'</tt></b>, which is then</li><li>encoded by the fourth rotor
--   (<tt>'4'</tt>), a <tt>"γ"</tt> rotor in the <tt>10</tt> position (and
--   <tt>'L'</tt> at the window), to <b><tt>'J'</tt></b>, which is
--   then</li><li>encoded by the reflector rotor (<tt>'U'</tt>), a
--   <tt>"b"</tt> reflector, to <b><tt>'I'</tt></b>, which reverses the
--   signal sending it back through the rotors, where it is
--   then</li><li>encoded in reverse by the fourth rotor (<tt>'4'</tt>), to
--   <b><tt>'Z'</tt></b>, which is then</li><li>encoded in reverse by the
--   third rotor (<tt>'3'</tt>), to <b><tt>'G'</tt></b>, which is
--   then</li><li>encoded in reverse by the second rotor (<tt>'2'</tt>), to
--   <b><tt>'Q'</tt></b>, which is then</li><li>encoded in reverse by the
--   first rotor (<tt>'1'</tt>), to <b><tt>'G'</tt></b>, which is
--   then</li><li>left unchanged by the plugboard (<tt>'P'</tt>), and
--   finally</li><li>displayed as <b><tt>'G'</tt></b></li></ul>Note that
--   (as follows from <a>Mapping</a>) the position of the marked letter at
--   each stage is the alphabetic position of the marked letter at the
--   previous stage.This can be represented schematically (with input
--   arriving and output exiting on the left) as</li>
--   <li><i><tt>"windows"</tt></i> The letters at the window (see
--   <a>windows</a>):<pre>LFAQ</pre></li>
--   <li><i><tt>"config"</tt></i> The specification of the configuration
--   (see <tt>configEnigmaExcept</tt>) in the same format used by
--   <tt>configEnigma</tt> and <tt>configEnigmaExcept</tt>, as a single
--   string:<pre>b-γ-V-VIII-II LFAQ UX.MO.KZ.AY.EF.PL
--   03.17.04.11</pre></li>
--   <li><i><tt>"encoding"</tt></i> The encoding of any valid letter being
--   encoded (see <a>showencoding</a>):<pre>K &gt; G</pre></li>
--   </ul>
--   
--   Note the "windows" and config" effectively display the same format as
--   <a>windows</a> and <tt>show</tt>, and are most useful in conjunction
--   with other options (e.g. <a>showencoding</a> and <a>showsteps</a>,
--   respectively) and for showing operation with
--   <a>displayEnigmaOperation</a>.
--   
--   See <a>displayEnigmaConfig</a> for further examples.
--   
--   Display functions are forgiving about the supplied format and will
--   accept a range of reasonable substitutes (e.g., <tt>"detailed"</tt> or
--   <tt>"schematic"</tt> for <tt>"internal"</tt>), and will treat
--   unrecognized formats as the default, <tt>"single"</tt>.
format :: DisplayOpts -> Format

-- | A <tt>Bool</tt> indicating whether to show encoding if not normally
--   shown for the specified format.
--   
--   If a valid letter is being encoded (one is either provided as an
--   argument to <a>displayEnigmaConfig</a>, or there is a message provided
--   as an argument to <a>displayEnigmaOperation</a> with a letter at the
--   displayed step) the letter and its encoding are indicated.
--   
--   This setting applies only to <tt>"windows"</tt> and <tt>"config"</tt>.
--   For example, where "windows" normally shows just
--   
--   <pre>
--   LFAQ
--   </pre>
--   
--   setting <tt>showencoding</tt> to <tt>True</tt> produces
--   
--   <pre>
--   LFAQ  K &gt; G
--   </pre>
showencoding :: DisplayOpts -> Bool

-- | A <a>MarkerSpec</a> that should be either a pair or characters (e.g.
--   <tt>"[]"</tt>) or a specification of a color (e.g, <tt>"red"</tt>) or
--   style (<tt>"bars"</tt>) to use to highlight the encoded character in
--   formats that show encoding. For example the default
--   <tt>markerspec</tt> of <tt>"bars"</tt> highlights the encoding (in,
--   e.g., the <tt>"single"</tt> format with a bar above and below the
--   encoding
--   
--   <pre>
--   K &gt; CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
--   </pre>
--   
--   and supplying a <tt>markerspec</tt> of <tt>"[]"</tt> instead
--   highlights the encoding of the letter by placing a <tt>"["</tt> to the
--   left and a <tt>"]"</tt> to the right of the encoding
--   
--   <pre>
--   K &gt; CMAWFEKLNV[G]HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
--   </pre>
--   
--   Invalid or unrecognized highlight specifications are treated as the
--   <tt>"bars"</tt>.
markerspec :: DisplayOpts -> MarkerSpec

-- | A <tt>Bool</tt> indicating whether to show step numbers, defaults to
--   <tt>False</tt>.
--   
--   Only relevant for operation display functions. See
--   <a>displayEnigmaOperation</a> for examples.
showsteps :: DisplayOpts -> Bool

-- | An <tt>Int</tt> indicating the number of steps to display, which
--   defaults to the length of a message if one is being displayed, and to
--   <tt>1</tt> otherwise. Values less than <tt>1</tt> are treated as the
--   default.
--   
--   Only relevant for operation display functions. See
--   <a>displayEnigmaOperation</a> for examples.
steps :: DisplayOpts -> DisplaySteps

-- | A (<a>synonym</a> for) <a>String</a>, indicating that this option will
--   be coerced to a valid valid <a>format</a> when used by display
--   functions.
type Format = String

-- | A (<a>synonym</a> for) <a>String</a>, indicating that this option will
--   be coerced to a valid valid <a>markerspec</a> when used by display
--   functions.
type MarkerSpec = String

-- | A (<a>synonym</a> for) <a>Int</a>, indicating that this option will be
--   coerced to a valid valid <a>steps</a> value when used by display
--   functions.
type DisplaySteps = Int

-- | A <tt>String</tt> representation of an <a>EnigmaConfig</a> using the
--   specified <a>DisplayOpts</a>.
--   
--   If an uppercase letter is provided, indicate that as input show its
--   encoding(s), as determined by the the <a>format</a> and
--   <a>showencoding</a> and, where for the <tt>format</tt>,
--   <a>markerspec</a>. Other characters will be ignored.
--   
--   For example, the illustrations given in the discussion of the
--   <a>format</a> option above can be created using (in order)
--   
--   <pre>
--   &gt;&gt;&gt; let cfg = step $ configEnigma "b-γ-V-VIII-II" "LFAP" "UX.MO.KZ.AY.EF.PL" "03.17.04.11"
--   
--   &gt;&gt;&gt; putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="single"}
--   K &gt; CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
--   
--   &gt;&gt;&gt; putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="internal"}
--   K &gt; ABCDEFGHIJK̲̅LMNOPQRSTUVWXYZ
--     P YBCDFEGHIJZ̲̅PONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
--     1 LORVFBQNGWKATHJSZPIYUDXEMC̲̅  Q  07  II
--     2 BJY̲̅INTKWOARFEMVSGCUDPHZQLX  A  24  VIII
--     3 ILHXUBZQPNVGKMCRTEJFADOYS̲̅W  F  16  V
--     4 YDSKZPTNCHGQOMXAUWJ̲̅FBRELVI  L  10  γ
--     R ENKQAUYWJI̲̅COPBLMDXZVFTHRGS         b
--     4 PUIBWTKJZ̲̅SDXNHMFLVCGQYROAE         γ
--     3 UFOVRTLCASMBNJWIHPYQEKZDXG̲̅         V
--     2 JARTMLQ̲̅VDBGYNEIUXKPFSOHZCW         VIII
--     1 LFZVXEINSOKAYHBRG̲̅CPMUDJWTQ         II
--     P YBCDFEG̲̅HIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
--   G &lt; CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="windows"}
--   LFAQ
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="config"}
--   b-γ-V-VIII-II LFAQ UX.MO.KZ.AY.EF.PL 03.17.04.11
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="encoding"}
--   K &gt; G
--   </pre>
--   
--   and other options can be freely combined (or omitted), for example
--   
--   <pre>
--   &gt;&gt;&gt; putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="single",markerspec="()"}
--   K &gt; CMAWFEKLNV(G)HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStrLn $ displayEnigmaConfig cfg 'K' displayOpts{format="config",showencoding=True}
--   b-γ-V-VIII-II LFAQ UX.MO.KZ.AY.EF.PL 03.17.04.11  K &gt; G
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStrLn $ displayEnigmaConfig cfg 'K' displayOpts
--   K &gt; CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
--   </pre>
displayEnigmaConfig :: EnigmaConfig -> Char -> DisplayOpts -> String

-- | A <a>String</a> representation of an Enigma machine's internal
--   configuration (see <a>displayEnigmaConfig</a> for details) and for
--   each subsequent configuration as it processes each letter of a
--   <a>Message</a>, subject to the provided <a>DisplayOpts</a>.
--   
--   In addition to the options that apply to the representation of each
--   individual configuration, <tt>DisplayOpts</tt> for this function
--   include options for specifying whether to run for a specific number of
--   steps and whether to include a step number in the representations.
--   
--   For example, these options applied to the default <tt>"single"</tt>
--   <a>format</a>
--   
--   <pre>
--   &gt;&gt;&gt; let cfg = configEnigma "b-γ-V-VIII-II" "LFAP" "UX.MO.KZ.AY.EF.PL" "03.17.04.11"
--   
--   &gt;&gt;&gt; putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts
--       OHNKJYSBTEDMLCARWPGIXZQUFV  LFAP  10 16 24 06
--   K &gt; CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
--   R &gt; HXETCUMASQNZGKRYJO̲̅IDFWVBPL  LFAR  10 16 24 08
--   I &gt; FGRJUABYW̲̅DZSXVQTOCLPENIMHK  LFAS  10 16 24 09
--   E &gt; SJWYN̲̅UZPQBVXRETHIMAOFKCLDG  LFAT  10 16 24 10
--   G &gt; EOKPAQW̲̅JLHCISTBDFVMNXRGUZY  LFAU  10 16 24 11
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{showsteps=True}
--   000      OHNKJYSBTEDMLCARWPGIXZQUFV  LFAP  10 16 24 06
--   001  K &gt; CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
--   002  R &gt; HXETCUMASQNZGKRYJO̲̅IDFWVBPL  LFAR  10 16 24 08
--   003  I &gt; FGRJUABYW̲̅DZSXVQTOCLPENIMHK  LFAS  10 16 24 09
--   004  E &gt; SJWYN̲̅UZPQBVXRETHIMAOFKCLDG  LFAT  10 16 24 10
--   005  G &gt; EOKPAQW̲̅JLHCISTBDFVMNXRGUZY  LFAU  10 16 24 11
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{showsteps=False,steps=2}
--       OHNKJYSBTEDMLCARWPGIXZQUFV  LFAP  10 16 24 06
--   K &gt; CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
--   R &gt; HXETCUMASQNZGKRYJO̲̅IDFWVBPL  LFAR  10 16 24 08
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{showsteps=False,steps=10}
--       OHNKJYSBTEDMLCARWPGIXZQUFV  LFAP  10 16 24 06
--   K &gt; CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS  LFAQ  10 16 24 07
--   R &gt; HXETCUMASQNZGKRYJO̲̅IDFWVBPL  LFAR  10 16 24 08
--   I &gt; FGRJUABYW̲̅DZSXVQTOCLPENIMHK  LFAS  10 16 24 09
--   E &gt; SJWYN̲̅UZPQBVXRETHIMAOFKCLDG  LFAT  10 16 24 10
--   G &gt; EOKPAQW̲̅JLHCISTBDFVMNXRGUZY  LFAU  10 16 24 11
--       IKOEDUXWAMBPJYCLSZQVFTHGNR  LFAV  10 16 24 12
--       RSWOUZNXTQLKPGDMJABIEYCHVF  LFAW  10 16 24 13
--       CUAMOTILGNWHDJERSPQFBZKYXV  LFAX  10 16 24 14
--       HXPVYZKAOTGSRWICUMLJQDNBEF  LFAY  10 16 24 15
--       QSXTPJNRUFMVKGZEAHBDILYCWO  LFAZ  10 16 24 16
--   </pre>
--   
--   to the <tt>"internal"</tt> <a>format</a>
--   
--   <pre>
--   &gt;&gt;&gt; putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{format="internal",showsteps=False,steps=2}
--       ABCDEFGHIJKLMNOPQRSTUVWXYZ
--     P YBCDFEGHIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
--     1 DMPSWGCROHXLBUIKTAQJZVEYFN  P  06  II
--     2 BJYINTKWOARFEMVSGCUDPHZQLX  A  24  VIII
--     3 ILHXUBZQPNVGKMCRTEJFADOYSW  F  16  V
--     4 YDSKZPTNCHGQOMXAUWJFBRELVI  L  10  γ
--     R ENKQAUYWJICOPBLMDXZVFTHRGS         b
--     4 PUIBWTKJZSDXNHMFLVCGQYROAE         γ
--     3 UFOVRTLCASMBNJWIHPYQEKZDXG         V
--     2 JARTMLQVDBGYNEIUXKPFSOHZCW         VIII
--     1 RMGAWYFJOTPLBZICSHDQNVEKXU         II
--     P YBCDFEGHIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
--       OHNKJYSBTEDMLCARWPGIXZQUFV
--   
--   K &gt; ABCDEFGHIJK̲̅LMNOPQRSTUVWXYZ
--     P YBCDFEGHIJZ̲̅PONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
--     1 LORVFBQNGWKATHJSZPIYUDXEMC̲̅  Q  07  II
--     2 BJY̲̅INTKWOARFEMVSGCUDPHZQLX  A  24  VIII
--     3 ILHXUBZQPNVGKMCRTEJFADOYS̲̅W  F  16  V
--     4 YDSKZPTNCHGQOMXAUWJ̲̅FBRELVI  L  10  γ
--     R ENKQAUYWJI̲̅COPBLMDXZVFTHRGS         b
--     4 PUIBWTKJZ̲̅SDXNHMFLVCGQYROAE         γ
--     3 UFOVRTLCASMBNJWIHPYQEKZDXG̲̅         V
--     2 JARTMLQ̲̅VDBGYNEIUXKPFSOHZCW         VIII
--     1 LFZVXEINSOKAYHBRG̲̅CPMUDJWTQ         II
--     P YBCDFEG̲̅HIJZPONMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
--   G &lt; CMAWFEKLNVG̲̅HBIUYTXZQOJDRPS
--   
--   R &gt; ABCDEFGHIJKLMNOPQR̲̅STUVWXYZ
--     P YBCDFEGHIJZPONMLQR̲̅STXVWUAK         UX.MO.KZ.AY.EF.PL
--     1 NQUEAPMFVJZSGIRYOH̲̅XTCWDLBK  R  08  II
--     2 BJYINTKW̲̅OARFEMVSGCUDPHZQLX  A  24  VIII
--     3 ILHXUBZQPNVGKMCRTEJFADO̲̅YSW  F  16  V
--     4 YDSKZPTNCHGQOMX̲̅AUWJFBRELVI  L  10  γ
--     R ENKQAUYWJICOPBLMDXZVFTHR̲̅GS         b
--     4 PUIBWTKJZSDXNHMFLV̲̅CGQYROAE         γ
--     3 UFOVRTLCASMBNJWIHPYQEK̲̅ZDXG         V
--     2 JARTMLQVDBG̲̅YNEIUXKPFSOHZCW         VIII
--     1 EYUWDHM̲̅RNJZXGAQFBOLTCIVSPK         II
--     P YBCDFEGHIJZPO̲̅NMLQRSTXVWUAK         UX.MO.KZ.AY.EF.PL
--   O &lt; HXETCUMASQNZGKRYJO̲̅IDFWVBPL
--   </pre>
--   
--   and to some of the other <a>format</a>s
--   
--   <pre>
--   &gt;&gt;&gt; putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{showencoding=True,format="windows",showsteps=True,steps=8}
--   000  LFAP
--   001  LFAQ  K &gt; G
--   002  LFAR  R &gt; O
--   003  LFAS  I &gt; W
--   004  LFAT  E &gt; N
--   005  LFAU  G &gt; W
--   006  LFAV
--   007  LFAW
--   008  LFAX
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{format="config",showsteps=True,steps=8,showencoding=True}
--   000  b-γ-V-VIII-II LFAP UX.MO.KZ.AY.EF.PL 03.17.04.11
--   001  b-γ-V-VIII-II LFAQ UX.MO.KZ.AY.EF.PL 03.17.04.11  K &gt; G
--   002  b-γ-V-VIII-II LFAR UX.MO.KZ.AY.EF.PL 03.17.04.11  R &gt; O
--   003  b-γ-V-VIII-II LFAS UX.MO.KZ.AY.EF.PL 03.17.04.11  I &gt; W
--   004  b-γ-V-VIII-II LFAT UX.MO.KZ.AY.EF.PL 03.17.04.11  E &gt; N
--   005  b-γ-V-VIII-II LFAU UX.MO.KZ.AY.EF.PL 03.17.04.11  G &gt; W
--   006  b-γ-V-VIII-II LFAV UX.MO.KZ.AY.EF.PL 03.17.04.11
--   007  b-γ-V-VIII-II LFAW UX.MO.KZ.AY.EF.PL 03.17.04.11
--   008  b-γ-V-VIII-II LFAX UX.MO.KZ.AY.EF.PL 03.17.04.11
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; putStr $ displayEnigmaOperation cfg "KRIEG" displayOpts{format="encoding",showsteps=True,showencoding=False}
--   000
--   001  K &gt; G
--   002  R &gt; O
--   003  I &gt; W
--   004  E &gt; N
--   005  G &gt; W
--   </pre>
--   
--   Note that first step of each of these displays represents the initial
--   configuration of the machine, but does not perform any encoding (as
--   explained in <a>step</a>).
--   
--   Also also that the second block of the <tt>"internal"</tt> display
--   example is the same as one illustrated for the <tt>"internal"</tt>
--   <a>format</a>, where it is explained in detail.
displayEnigmaOperation :: EnigmaConfig -> Message -> DisplayOpts -> String

-- | A list representation of the operation of an enigma machine,
--   equivalent to
--   
--   <pre>
--   lines $ displayEnigmaOperation
--   </pre>
listEnigmaOperation :: EnigmaConfig -> Message -> DisplayOpts -> [String]

-- | Show the conventionally formatted encoding of a <a>Message</a> by an
--   (initial) Enigma machine configuration.
--   
--   <pre>
--   &gt;&gt;&gt; let cfg = configEnigma "c-β-V-VI-VIII" "CDTJ" "AE.BF.CM.DQ.HU.JN.LX.PR.SZ.VW" "05.16.05.12"
--   
--   &gt;&gt;&gt; putStr $ displayEnigmaEncoding cfg "FOLGENDES IST SOFORT BEKANNTZUGEBEN"
--   RBBF PMHP HGCZ XTDY GAHG UFXG EWKB LKGJ
--   </pre>
displayEnigmaEncoding :: EnigmaConfig -> Message -> String
