modularize

This commit is contained in:
Kierán Meinhardt
2020-06-24 13:28:14 +02:00
parent e3322f4930
commit 5bed7d4f93
3 changed files with 139 additions and 99 deletions

View File

@@ -1,12 +1,16 @@
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE LambdaCase #-}
module Lib module Lib
( someFunc ( someFunc
) )
where where
import Phonology
import Util ( replaceSublist )
import Control.Monad ( forM_ ) import Control.Monad ( forM_ )
import Data.List ( zip3 )
{- {-
import Data.Void import Data.Void
import qualified Text.Megaparsec as Parsec import qualified Text.Megaparsec as Parsec
@@ -43,112 +47,28 @@ parseRoot = () <$ do
-} -}
data Manner = Tenuis | Media | MediaAspirata
deriving (Show, Eq)
data Place = Labial | Dental | Palatal | Velar | Labiovelar
deriving (Show, Eq)
data Phoneme
= E | O | A | E_ | O_ | A_
| I | U | N | M | R | L
| P | B | Bh | T | D | Dh | Kj | Gj | Gjh | K | G | Gh | Kw | Gw | Gwh | S | H1 | H2 | H3 | H
deriving (Eq, Ord)
instance Show Phoneme where
show = \case
E -> "e"
O -> "o"
A -> "a"
E_ -> "ē"
O_ -> "ō"
A_ -> "ā"
I -> "i"
U -> "u"
N -> "n"
M -> "m"
R -> "r"
L -> "l"
P -> "p"
B -> "b"
Bh -> "bh"
T -> "t"
D -> "d"
Dh -> "dh"
Kj -> ""
Gj -> "ǵ"
Gjh -> "ǵh"
K -> "k"
G -> "g"
Gh -> "gh"
Kw -> ""
Gw -> ""
Gwh -> "gʷh"
S -> "s"
H1 -> "h₁"
H2 -> "h₂"
H3 -> "h₃"
H -> "H"
data FeatureSet
= Vowel
| Resonant
| Plosive { manner :: Manner, place :: Place }
| Sibilant
| Laryngeal
deriving (Show, Eq)
isPlosive :: FeatureSet -> Bool
isPlosive (Plosive _ _) = True
isPlosive _ = False
features :: Phoneme -> FeatureSet
features phoneme
| phoneme == S = Sibilant
| phoneme `elem` [E, O, A, E_, O_, A_] = Vowel
| phoneme `elem` [H1, H2, H3, H] = Laryngeal
| phoneme `elem` [I, U, N, M, R, L] = Resonant
| otherwise = Plosive
{ manner = if
| phoneme `elem` [P, T, K, Kj, Kw] -> Tenuis
| phoneme `elem` [B, D, G, Gj, Gw] -> Media
| phoneme `elem` [Bh, Dh, Gh, Gjh, Gwh] -> MediaAspirata
, place = if
| phoneme `elem` [P, B, Bh] -> Labial
| phoneme `elem` [T, D, Dh] -> Dental
| phoneme `elem` [Kj, Gj, Gjh] -> Palatal
| phoneme `elem` [K, G, Gh] -> Velar
| phoneme `elem` [Kw, Gw, Gwh] -> Labiovelar
}
syllabify :: [Phoneme] -> [Bool] syllabify :: [Phoneme] -> [Bool]
syllabify = foldr isSonant [] syllabify = replaceSublist [True, True] [True, False] -- replace VV by VC
. foldr isSonant []
where where
hasToBeSyllabic p = features p == Vowel hasToBeSyllabic p = features p == Vowel
canBeSyllabic p = features p `elem` [Vowel, Resonant, Laryngeal] canBeSyllabic p = features p `elem` [Vowel, Resonant, Laryngeal]
isSonant current xs = case xs of isSonant current xs = case xs of
[] -> [hasToBeSyllabic current] -- last phoneme in word [] -> [canBeSyllabic current] -- make last phoneme in word syllabic
previousIsSonant : _ -> if previousIsSonant previousIsSonant : _ -> if previousIsSonant
then hasToBeSyllabic current : xs -- only vowels are sonant, the rest can be consonantal then hasToBeSyllabic current : xs -- only vowels are sonant, the rest can be consonantal
else canBeSyllabic current : xs -- make syllabic if previous is not syllabic else canBeSyllabic current : xs -- make syllabic if previous is not syllabic
showSyllabic :: Phoneme -> Bool -> String
showSyllabic phoneme syllabic = case (phoneme, syllabic) of
(I , False) -> "y"
(U , False) -> "w"
(N , True ) -> ""
(M , True ) -> ""
(R , True ) -> ""
(L , True ) -> ""
(H1, True ) -> "ə₁"
(H2, True ) -> "ə₂"
(H3, True ) -> "ə₃"
(H , True ) -> "ə"
_ -> show phoneme
printSyllabified ps = syllableCores :: [Phoneme] -> [Bool]
putStr (concatMap show ps) >> putChar ' ' >> print (syllabify ps) syllableCores = localMax . (++ [0]) . ([0] ++) . map (sonority . features)
where
localMax xs = map project $ zip3 xs (tail xs) (drop 2 xs)
where project (x, y, z) = x <= y && y >= z
-- chunkSyllables :: [Bool] -> [[Bool]]
-- chunkSyllables = _
someFunc :: IO () someFunc :: IO ()
someFunc = do someFunc = do
@@ -171,6 +91,11 @@ someFunc = do
, [N, D, R, Kj, T, O, S] , [N, D, R, Kj, T, O, S]
, [U, N, T, O, S] , [U, N, T, O, S]
, [D, U, I, D, Kj, M, T] , [D, U, I, D, Kj, M, T]
, [Kj, L, U, Dh, I]
, [H1, N, E, U, N]
, [H2, U, E, H1, N, T, O, S]
] ]
forM_ pieLines forM_ pieLines $ \line -> do
$ \line -> putStrLn $ concat $ zipWith showSyllabic line (syllabify line) putStr $ concatMap show line
putChar ' '
putStrLn $ concat $ zipWith showSyllabic line (syllabify line)

105
src/Phonology.hs Normal file
View File

@@ -0,0 +1,105 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiWayIf #-}
module Phonology where
data Manner = MediaAspirata | Media | Tenuis
deriving (Show, Eq, Ord)
data Place = Labial | Dental | Palatal | Velar | Labiovelar
deriving (Show, Eq, Ord)
data Phoneme
= E | O | A | E_ | O_ | A_
| I | U | N | M | R | L
| P | B | Bh | T | D | Dh | Kj | Gj | Gjh | K | G | Gh | Kw | Gw | Gwh | S | H1 | H2 | H3 | H
deriving (Eq, Ord)
instance Show Phoneme where
show = \case
E -> "e"
O -> "o"
A -> "a"
E_ -> "ē"
O_ -> "ō"
A_ -> "ā"
I -> "i"
U -> "u"
N -> "n"
M -> "m"
R -> "r"
L -> "l"
P -> "p"
B -> "b"
Bh -> "bh"
T -> "t"
D -> "d"
Dh -> "dh"
Kj -> ""
Gj -> "ǵ"
Gjh -> "ǵh"
K -> "k"
G -> "g"
Gh -> "gh"
Kw -> ""
Gw -> ""
Gwh -> "gʷh"
S -> "s"
H1 -> "h₁"
H2 -> "h₂"
H3 -> "h₃"
H -> "H"
data FeatureSet
= Vowel
| Resonant
| Laryngeal
| Sibilant
| Plosive { manner :: Manner, place :: Place }
deriving (Show, Eq, Ord)
sonority :: FeatureSet -> Int
sonority = \case
Vowel -> 4
Resonant -> 3
Laryngeal -> 3
Sibilant -> 2
Plosive _ _ -> 1
isPlosive :: FeatureSet -> Bool
isPlosive (Plosive _ _) = True
isPlosive _ = False
features :: Phoneme -> FeatureSet
features phoneme
| phoneme == S = Sibilant
| phoneme `elem` [E, O, A, E_, O_, A_] = Vowel
| phoneme `elem` [H1, H2, H3, H] = Laryngeal
| phoneme `elem` [I, U, N, M, R, L] = Resonant
| otherwise = Plosive
{ manner = if
| phoneme `elem` [P, T, K, Kj, Kw] -> Tenuis
| phoneme `elem` [B, D, G, Gj, Gw] -> Media
| phoneme `elem` [Bh, Dh, Gh, Gjh, Gwh] -> MediaAspirata
, place = if
| phoneme `elem` [P, B, Bh] -> Labial
| phoneme `elem` [T, D, Dh] -> Dental
| phoneme `elem` [Kj, Gj, Gjh] -> Palatal
| phoneme `elem` [K, G, Gh] -> Velar
| phoneme `elem` [Kw, Gw, Gwh] -> Labiovelar
}
showSyllabic :: Phoneme -> Bool -> String
showSyllabic phoneme syllabic = case (phoneme, syllabic) of
(I , False) -> "y"
(U , False) -> "w"
(N , True ) -> ""
(M , True ) -> ""
(R , True ) -> ""
(L , True ) -> ""
(H1, True ) -> "ə₁"
(H2, True ) -> "ə₂"
(H3, True ) -> "ə₃"
(H , True ) -> "ə"
_ -> show phoneme

10
src/Util.hs Normal file
View File

@@ -0,0 +1,10 @@
module Util where
import Data.List ( isPrefixOf )
replaceSublist :: Eq a => [a] -> [a] -> [a] -> [a]
replaceSublist _ _ [] = []
replaceSublist list replacement xss@(x : xs) = if list `isPrefixOf` xss
then replacement ++ replaceSublist list replacement (drop (length list) xss)
else x : replaceSublist list replacement xs