{-| Module : RandomText Description : Contextual randomized text Copyright : (c) CNRS / Alexandre Delanoe, 2017-present License : AGPL + CECILL v3 Maintainer : alexandre.delanoe@iscpif.fr Stability : experimental Portability : POSIX How semantic emerge from contextualized randomness can be experimented with these simple functions; randomSentences: randomizes sentences in a paragraph. randomWords : randomizes words in a sentence. randomChars : randomizes chars in a word. TODO: add some tests as examples. -} module Gargantext.Components.RandomText where import Prelude import Data.Array (drop, dropEnd, filter, foldl, head, length, tail, take, takeEnd, (!!)) import Data.Maybe (Maybe(Nothing, Just), fromJust) import Data.String (Pattern(..), split) import Data.String.CodeUnits (fromCharArray, toCharArray) import Effect (Effect) import Effect.Random (randomInt) import Partial (crash) import Partial.Unsafe (unsafePartial) ------------------------------------------------------------------- randomSentences :: String -> Effect String randomSentences ss = case (length (sentences ss)) >= 5 of true -> foldl (\a b -> a <> "." <> b) "" <$> randomPart (sentences ss) _ -> pure ss randomWords :: String -> Effect String randomWords ws = case (length (words ws)) >= 5 of true -> foldl (\a b -> a <> " " <> b) "" <$> randomPart (words ws) _ -> pure ws randomChars :: String -> Effect String randomChars word = case (length (toCharArray word)) >= 5 of true -> fromCharArray <$> randomPart (toCharArray word) _ -> pure word ------------------------------------------------------------------- words :: String -> Array String words sentence = filter ((/=) "") $ split (Pattern " ") sentence sentences :: String -> Array String sentences paragraph = filter ((/=) "") $ split (Pattern ".") paragraph ------------------------------------------------------------------- data RandomWheel a = RandomWheel { before :: Array a , during :: a , after :: Array a } randomPart :: forall b. Array b -> Effect (Array b) randomPart array = randomArrayPoly middle >>= \(middle') -> pure ( start <> middle' <> end) where start = take 2 array middle = dropEnd 2 $ drop 2 array end = takeEnd 2 array randomArrayPoly :: forall a. Array a -> Effect (Array a) randomArrayPoly wheel = case head wheel of Nothing -> pure [] Just wheel' -> randomWheel (RandomWheel { before:wheel, during:wheel', after:[]}) >>= \(RandomWheel rand) -> (pure rand.after) randomWheel :: forall b. RandomWheel b -> Effect (RandomWheel b) randomWheel (RandomWheel {before:[], during:d, after:a}) = pure (RandomWheel {before:[], during:d, after:a}) randomWheel (RandomWheel {before:b, during:d, after:a}) = do RandomWheel {before:b', during:d', after:a'} <- randomArray b randomWheel $ RandomWheel {before:b', during:d', after:(a <> [d'])} randomArray :: forall b. Array b -> Effect (RandomWheel b) randomArray array = unsafePartial $ do n <- randomInt 0 (length array - 1) let maybeDuring = (array !! n) case maybeDuring of Nothing -> crash "[ERROR] It should never happen." Just during -> pure $ RandomWheel { before : remove n array , during : during , after : [] } remove :: forall a. Int -> Array a -> Array a remove n [] = [] remove n xs = unsafePartial $ case n of 0 -> fromJust $ tail xs _ -> (take n xs) <> (drop (n+1) xs) -------------------------------------------------------------------