packages feed

ipa-0.3.1: src/Language/IPA/QQ.hs

{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeApplications #-}

-- |
module Language.IPA.QQ
    ( -- * IPA
      syllable
    , segment
    , syllables
      -- * X-SAMPA
    , segmentXS
    , syllableXS
    , syllablesXS
    ) where

import           Control.Exception          ( displayException )

import           Data.Text                  ( Text )
import qualified Data.Text                  as T

import           Language.Haskell.TH.Quote  ( QuasiQuoter(..) )
import           Language.Haskell.TH.Syntax ( Lift(lift) )
import           Language.IPA.Parser
                 ( parseSegment
                 , parseSegmentXSampa
                 , parseSyllable
                 , parseSyllableXSampa
                 , parseSyllables
                 , parseSyllablesXSampa
                 )
import           Language.IPA.Types         ( IPAException )

-- | Construct a compile-time 'Language.IPA.Types.Segment' using IPA notation
--
-- >>> [segment|ɣ|]
-- Consonant (Pulmonic Voiced Velar (Fricative NonSibilant))
segment :: QuasiQuoter
segment = liftQQ parseSegment

-- | Construct a compile-time 'Language.IPA.Types.Syllable' using IPA notation
--
-- >>> [syllable|ɣa˧˨|]
-- WithSuprasegmentalFeature (LexicalToneContour LowFalling)
--   (Syllable [ Consonant (Pulmonic Voiced Velar (Fricative NonSibilant))
--             , Vowel (Pure Open Front Unrounded)
--             ])
syllable :: QuasiQuoter
syllable = liftQQ (parseSyllable @[])

-- | Construct a compile-time @['Language.IPA.Types.Syllable']@ using IPA notation
syllables :: QuasiQuoter
syllables = liftQQ (parseSyllables @[])

-- | Construct a compile-time 'Language.IPA.Types.Segment' using X-SAMPA notation.
-- This may be more convenient than using text values - X-SAMPA inexplicably chose
-- to use backslashes as semantic tokens, which of course must be escaped
--
-- >>> [segmentXS|?\|]
-- Consonant (Pulmonic Voiced Pharyngeal (Fricative NonSibilant))
segmentXS :: QuasiQuoter
segmentXS = liftQQ parseSegmentXSampa

-- | Construct a compile-time 'Language.IPA.Types.Syllable' using X-SAMPA notation
syllableXS :: QuasiQuoter
syllableXS = liftQQ (parseSyllableXSampa @[])

-- | Construct a compile-time @['Language.IPA.Types.Syllable']@ using
-- X-SAMPA notation
syllablesXS :: QuasiQuoter
syllablesXS = liftQQ (parseSyllablesXSampa @[])

liftQQ :: Lift a => (Text -> Either IPAException a) -> QuasiQuoter
liftQQ f = QuasiQuoter { .. }
  where
    quoteExp str = either (fail . displayException) lift (f $ T.pack str)

    quotePat _ = fail errorMsg

    quoteType _ = fail errorMsg

    quoteDec _ = fail errorMsg

    errorMsg     = "Unsupported"