module Text.Seonbi.Hangul
( JamoTriple
, fromJamoTriple
, isHangulSyllable
, toJamoTriple
) where
type JamoTriple = (Char, Char, Maybe Char)
isHangulSyllable :: Char -> Bool
isHangulSyllable :: Char -> Bool
isHangulSyllable Char
c =
Char
c forall a. Ord a => a -> a -> Bool
>= Char
'\xac00' Bool -> Bool -> Bool
&& Char
c forall a. Ord a => a -> a -> Bool
<= Char
'\xd7a3';
syllableBase :: Int
syllableBase :: Int
syllableBase = Int
0xac00
initialBase :: Int
initialBase :: Int
initialBase = Int
0x1100
vowelBase :: Int
vowelBase :: Int
vowelBase = Int
0x1161
finalBase :: Int
finalBase :: Int
finalBase = Int
0x11a7
vowelCount :: Int
vowelCount :: Int
vowelCount = Int
21;
finalCount :: Int
finalCount :: Int
finalCount = Int
28;
toJamoTriple :: Char -> Maybe JamoTriple
toJamoTriple :: Char -> Maybe JamoTriple
toJamoTriple Char
c
| Char -> Bool
isHangulSyllable Char
c = forall a. a -> Maybe a
Just
( forall a. Enum a => Int -> a
toEnum forall a b. (a -> b) -> a -> b
$ Int
initialBase forall a. Num a => a -> a -> a
+ ((Int
syllable forall a. Integral a => a -> a -> a
`div` Int
finalCount) forall a. Integral a => a -> a -> a
`div` Int
vowelCount)
, forall a. Enum a => Int -> a
toEnum forall a b. (a -> b) -> a -> b
$ Int
vowelBase forall a. Num a => a -> a -> a
+ ((Int
syllable forall a. Integral a => a -> a -> a
`div` Int
finalCount) forall a. Integral a => a -> a -> a
`mod` Int
vowelCount)
, case Int
syllable forall a. Integral a => a -> a -> a
`mod` Int
finalCount of
Int
0 -> forall a. Maybe a
Nothing
Int
f -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Enum a => Int -> a
toEnum (Int
finalBase forall a. Num a => a -> a -> a
+ Int
f)
)
| Bool
otherwise = forall a. Maybe a
Nothing
where
syllable :: Int
syllable :: Int
syllable = forall a. Enum a => a -> Int
fromEnum Char
c forall a. Num a => a -> a -> a
- Int
syllableBase
fromJamoTriple :: JamoTriple -> Maybe Char
fromJamoTriple :: JamoTriple -> Maybe Char
fromJamoTriple (Char
initial, Char
vowel, Maybe Char
final)
| Int
initialIndex forall a. Ord a => a -> a -> Bool
< Int
0 = forall a. Maybe a
Nothing
| Int
initialIndex forall a. Ord a => a -> a -> Bool
> Int
18 = forall a. Maybe a
Nothing
| Int
vowelIndex forall a. Ord a => a -> a -> Bool
< Int
0 = forall a. Maybe a
Nothing
| Int
vowelIndex forall a. Ord a => a -> a -> Bool
> Int
20 = forall a. Maybe a
Nothing
| Int
finalIndex forall a. Ord a => a -> a -> Bool
< Int
0 = forall a. Maybe a
Nothing
| Int
finalIndex forall a. Ord a => a -> a -> Bool
> Int
27 = forall a. Maybe a
Nothing
| Bool
otherwise = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Enum a => Int -> a
toEnum forall a b. (a -> b) -> a -> b
$ Int
syllableBase forall a. Num a => a -> a -> a
+
(Int
initialIndex forall a. Num a => a -> a -> a
* Int
vowelCount forall a. Num a => a -> a -> a
+ Int
vowelIndex) forall a. Num a => a -> a -> a
* Int
finalCount forall a. Num a => a -> a -> a
+ Int
finalIndex
where
initialIndex :: Int
initialIndex :: Int
initialIndex = forall a. Enum a => a -> Int
fromEnum Char
initial forall a. Num a => a -> a -> a
- Int
initialBase
vowelIndex :: Int
vowelIndex :: Int
vowelIndex = forall a. Enum a => a -> Int
fromEnum Char
vowel forall a. Num a => a -> a -> a
- Int
vowelBase
finalIndex :: Int
finalIndex :: Int
finalIndex = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Int
0 (\ Char
f -> forall a. Enum a => a -> Int
fromEnum Char
f forall a. Num a => a -> a -> a
- Int
finalBase) Maybe Char
final