summaryrefslogtreecommitdiff
path: root/DobutokO/Poetry/StrictV.hs
blob: c5f87d0b45840098801283c54f85a7d6b06a1dd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
-- |
-- Module      :  DobutokO.Poetry.StrictV
-- Copyright   :  (c) OleksandrZhabenko 2020
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  olexandr543@yahoo.com
--
-- Helps to order the 7 or less Ukrainian words (or their concatenations) 
-- to obtain (to some extent) suitable for poetry or music text. The main 
-- module in the library that imports all other ones except Main.

{-# LANGUAGE CPP, BangPatterns #-}

module DobutokO.Poetry.StrictV where

#ifdef __GLASGOW_HASKELL__
#if __GLASGOW_HASKELL__>=804
/* code that applies only to GHC 8.4.* and higher versions */
import Data.Semigroup ((<>))
import Prelude hiding ((<>))
#endif
#endif

import qualified Data.Vector as V
import qualified Data.List as L (permutations)

-- | Given a 'String' consisting of no more than 7 Ukrainian words [some of them can be created by concatenation with preserving the Ukrainian 
-- pronunciation of the parts, e. g. \"так як\" (actually two correct Ukrainian words and a single conjunction) can be written \"такйак\" 
-- (one phonetical Ukrainian word transformed literally with preserving phonetical structure), if you would not like to treat them separately], 
-- it returns a 'V.Vector' of possible combinations without repeating of the words in different order and for each of them appends also 
-- the information about 'uniquenessPeriods' to it and finds out three different metrics -- named \"norms\". 
-- 
-- Afterwards, depending on these norms some phonetical properties of the words can be specified that 
-- allow to use them poetically or to create a varied melody with them. 
uniquenessVariants2GN :: V.Vector ([Int] -> Int) -> (String -> [Int]) -> String -> V.Vector ([Int],V.Vector Int, String)
uniquenessVariants2GN vN g !xs = uniquenessVariants2GNP [] [] vN g xs 
{-# INLINE uniquenessVariants2GN #-}
        
-- | Generalized variant of 'uniquenessVariants2GN' with prepending and appending 'String' (given as the first and the second argument). 
uniquenessVariants2GNP :: String -> String -> V.Vector ([Int] -> Int) -> (String -> [Int]) -> String -> V.Vector ([Int],V.Vector Int, String)
uniquenessVariants2GNP !ts !us vN g !xs 
  | null . words $ xs = V.empty
  | otherwise = let !v0 = V.fromList . take 8 . words $ xs in
     V.fromList . map ((\vs -> let !rs = g vs in (rs, (V.map (\f -> f rs) vN), vs)) . unwords . preAppend ts [us] . V.toList . 
       V.backpermute v0 . V.fromList) . L.permutations $ ([0..(V.length v0 - 1)]::[Int])


preAppend :: [a] -> [[a]] -> [[a]] -> [[a]]
#ifdef __GLASGOW_HASKELL__
#if __GLASGOW_HASKELL__>=804
preAppend ts !uss tss = ts:tss <> uss
#endif
#endif
#ifdef __GLASGOW_HASKELL__
#if __GLASGOW_HASKELL__<804
preAppend ts !uss tss = ts:tss ++ uss
#endif
#endif
{-# INLINE preAppend #-}