{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Language.IPA
(
ipaToXSampa
, xSampaToIpa
, toIPA'
, toXSampa'
, isValid
, isValidSegment
, isValidSyllable
, isObstruent
, isSonorant
, isLabial
, isCoronal
, isDorsal
, isLaryngeal
, isRhotic
, isLiquid
, module M
) where
import Control.Exception ( throw )
import Data.Maybe ( fromMaybe )
import Data.Text ( Text )
import Language.IPA.Class as M
import Language.IPA.Parser as M
import Language.IPA.Types as M
ipaToXSampa :: IPA -> Maybe XSampa
ipaToXSampa :: IPA -> Maybe XSampa
ipaToXSampa IPA { .. } =
(IPAException -> Maybe XSampa)
-> (Syllable [] -> Maybe XSampa)
-> Either IPAException (Syllable [])
-> Maybe XSampa
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe XSampa -> IPAException -> Maybe XSampa
forall a b. a -> b -> a
const Maybe XSampa
forall a. Maybe a
Nothing) Syllable [] -> Maybe XSampa
forall a. ReprXSampa a => a -> Maybe XSampa
toXSampa (Text -> Either IPAException (Syllable [])
forall a. ReprIPA a => Text -> Either IPAException a
parseIPA @(Syllable []) Text
unIPA)
xSampaToIpa :: XSampa -> Maybe IPA
xSampaToIpa :: XSampa -> Maybe IPA
xSampaToIpa XSampa { .. } =
(IPAException -> Maybe IPA)
-> (Syllable [] -> Maybe IPA)
-> Either IPAException (Syllable [])
-> Maybe IPA
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe IPA -> IPAException -> Maybe IPA
forall a b. a -> b -> a
const Maybe IPA
forall a. Maybe a
Nothing) Syllable [] -> Maybe IPA
forall a. ReprIPA a => a -> Maybe IPA
toIPA (Text -> Either IPAException (Syllable [])
forall a. ReprXSampa a => Text -> Either IPAException a
parseXSampa @(Syllable []) Text
unXSampa)
toIPA' :: ReprIPA a => a -> IPA
toIPA' :: a -> IPA
toIPA' x :: a
x = IPA -> Maybe IPA -> IPA
forall a. a -> Maybe a -> a
fromMaybe (IPAException -> IPA
forall a e. Exception e => e -> a
throw (IPAException -> IPA) -> IPAException -> IPA
forall a b. (a -> b) -> a -> b
$ Text -> IPAException
InvalidIPA "Illegal IPA value") (a -> Maybe IPA
forall a. ReprIPA a => a -> Maybe IPA
toIPA a
x)
toXSampa' :: ReprXSampa a => a -> XSampa
toXSampa' :: a -> XSampa
toXSampa' x :: a
x = XSampa -> Maybe XSampa -> XSampa
forall a. a -> Maybe a -> a
fromMaybe (IPAException -> XSampa
forall a e. Exception e => e -> a
throw (IPAException -> XSampa) -> IPAException -> XSampa
forall a b. (a -> b) -> a -> b
$ Text -> IPAException
InvalidXSampa "Illegal X-SAMPA value")
(a -> Maybe XSampa
forall a. ReprXSampa a => a -> Maybe XSampa
toXSampa a
x)
isValid :: forall a. ReprIPA a => Text -> Bool
isValid :: Text -> Bool
isValid t :: Text
t = (IPAException -> Bool)
-> (a -> Bool) -> Either IPAException a -> Bool
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Bool -> IPAException -> Bool
forall a b. a -> b -> a
const Bool
False) (Bool -> a -> Bool
forall a b. a -> b -> a
const Bool
True) (Text -> Either IPAException a
forall a. ReprIPA a => Text -> Either IPAException a
parseIPA @a Text
t)
isValidSegment :: Text -> Bool
isValidSegment :: Text -> Bool
isValidSegment = ReprIPA Segment => Text -> Bool
forall a. ReprIPA a => Text -> Bool
isValid @Segment
isValidSyllable :: Text -> Bool
isValidSyllable :: Text -> Bool
isValidSyllable = ReprIPA (Syllable []) => Text -> Bool
forall a. ReprIPA a => Text -> Bool
isValid @(Syllable [])
isObstruent :: Segment -> Bool
isObstruent :: Segment -> Bool
isObstruent = \case
PulmonicConsonant _ _ manner :: Manner
manner -> case Manner
manner of
Plosive -> Bool
True
Fricative _ -> Bool
True
Affricate _ -> Bool
True
_ -> Bool
False
_ -> Bool
False
isSonorant :: Segment -> Bool
isSonorant :: Segment -> Bool
isSonorant = Bool -> Bool
not (Bool -> Bool) -> (Segment -> Bool) -> Segment -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Segment -> Bool
isObstruent
isLabial :: Consonant -> Bool
isLabial :: Consonant -> Bool
isLabial = \case
Pulmonic _ place :: Place
place _ -> case Place
place of
Bilabial -> Bool
True
LabioDental -> Bool
True
LinguoLabial -> Bool
True
_ -> Bool
False
_ -> Bool
False
isCoronal :: Consonant -> Bool
isCoronal :: Consonant -> Bool
isCoronal = \case
Pulmonic _ Palatal (Fricative Sibilant) -> Bool
True
Pulmonic _ place :: Place
place _ -> case Place
place of
Dental -> Bool
True
Alveolar -> Bool
True
PostAlveolar -> Bool
True
Retroflex -> Bool
True
_ -> Bool
False
_ -> Bool
False
isDorsal :: Consonant -> Bool
isDorsal :: Consonant -> Bool
isDorsal = \case
Pulmonic _ place :: Place
place _ -> case Place
place of
Palatal -> Bool
True
Velar -> Bool
True
Uvular -> Bool
True
_ -> Bool
False
_ -> Bool
False
isLaryngeal :: Consonant -> Bool
isLaryngeal :: Consonant -> Bool
isLaryngeal = \case
Pulmonic _ place :: Place
place _ -> case Place
place of
Pharyngeal -> Bool
True
Glottal -> Bool
True
_ -> Bool
False
_ -> Bool
False
isRhotic :: Consonant -> Bool
isRhotic :: Consonant -> Bool
isRhotic = \case
Pulmonic Voiced Uvular (Fricative NonSibilant) -> Bool
True
Pulmonic _ Uvular Trill -> Bool
True
Pulmonic _ place :: Place
place manner :: Manner
manner
| Place
place Place -> [Place] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ Place
Alveolar, Place
Retroflex ] -> case Manner
manner of
Approximant -> Bool
True
Trill -> Bool
True
Flap -> Bool
True
_ -> Bool
False
| Bool
otherwise -> Bool
False
_ -> Bool
False
isLiquid :: Consonant -> Bool
isLiquid :: Consonant -> Bool
isLiquid c :: Consonant
c
| Consonant -> Bool
isRhotic Consonant
c = Bool
True
| Bool
otherwise = case Consonant
c of
Pulmonic Voiced _ LateralApproximant -> Bool
True
_ -> Bool
False