Hi All,<br><br>I wrote a program which permutates a list words with some rules. For example if I feed it a list like:<br><br>banana<br>waterloo<br>vraag<br><br>It gives back the list: <br><br>banana<br>b@nana<br>ban@na<br>
b@n@na<br>banan@<br>b@nan@<br>ban@n@<br>b@n@n@<br>waterloo<br>wa+erloo<br>water|oo<br>waterl0o<br>etc<br><br>However I have the feeling I am doing things to complicated. I am still a beginner. Would someone like to help me simplify somethings. If you think this is inappropriate please state also. I am not offended then. I understand you are offering your spare time to help me.<br>
<br>The first thing I don&#39;t get is this. I recognize some things could be rewritten with a bind operator (because of the concat $ fmap), but I am puzzled how:<br><br>mutateWords :: [Char] -&gt; [[Char]] <br>
mutateWords word = nub.concat $ fmap snd &lt;$&gt; fmap unzip &lt;$&gt; ( foldr(\x z -&gt;  <br>
                        let char = snd x <br>
                            nm = number word  <br>
                            lst = fst x <br>
                        in (insertAt char nm &lt;$&gt; lst) : z <br>
                ) [[]] $ mw word ) <br><br><br><br><br>Here is the full code: <br><br><br>import Data.List <br>import System <br>import System.IO <br>import Control.Applicative <br> <br> <br>---CONFIG section <br> <br>leat = [&#39;s&#39; ==&gt; &#39;$&#39;, &#39;t&#39; ==&gt; &#39;+&#39;, &#39;l&#39; ==&gt; &#39;|&#39;, &#39;o&#39; ==&gt; &#39;0&#39;,&#39;e&#39; ==&gt; &#39;3&#39;, &#39;a&#39; ==&gt; &#39;@&#39;, &#39;v&#39; ==&gt; &#39;^&#39;] <br>
 <br>leata = fst.unzip $ leat <br>leatb = snd.unzip $ leat <br> <br>-- Perl like assoc lists <br>infixl 1 ==&gt; <br>a ==&gt; b = (a, b) <br> <br> <br>-- Flipped fmap sometimes nicer <br>infixl 4 &lt;$$&gt; <br> <br>xs &lt;$$&gt; f = f &lt;$&gt; xs <br>
 <br> <br>-- first I need to find  the positions of the mutatable charachters. <br>findPositions :: [Char] -&gt; [[Int]] <br>findPositions xs = take (length index) $ index &lt;*&gt; [xs] <br>        where index = elemIndices &lt;$&gt; leata <br>
 <br>-- And generate all subsequences <br>findSubSeq :: [Char] -&gt; [[[Int]]] <br>findSubSeq  = fmap subsequences &lt;$&gt; findPositions <br> <br> <br>-- Only change elements which needs to be changed <br>insertAt :: Char -&gt; [(Int, Char)] -&gt; [Int] -&gt; [(Int,Char)] <br>
insertAt c xs ps = xs &lt;$$&gt; (\x -&gt;  <br>                if (fst x) `elem` ps <br>                        then (fst x , c) <br>                        else x <br>                ) <br>-- Couples character to mutable positions        <br>
mw word = (findSubSeq word) `zip` leatb  <br> <br>number = zip [0..] <br> <br>mutateWords :: [Char] -&gt; [[Char]] <br>mutateWords word = nub.concat $ fmap snd &lt;$&gt; fmap unzip &lt;$&gt; ( foldr(\x z -&gt;  <br>                        let char = snd x <br>
                            nm = number word  <br>                            lst = fst x <br>                        in (insertAt char nm &lt;$&gt; lst) : z <br>                ) [[]] $ mw word ) <br> <br>generateAll :: [Char] -&gt; [[Char]] <br>
generateAll word = g lea $ mutateWords word<br>    where   g 0 words = words<br>                g n words = g (n - 1) (nub  $  words &gt;&gt;= mutateWords )<br>                lea = length leata<br>main = do<br>        filename &lt;- getArgs<br>
        wordlist &lt;- readFile $ filename !! 0<br>        let a = (words wordlist) &gt;&gt;= generateAll<br>        mapM_ putStrLn  a<br>                              <br>-- <br>Flatliner ICT Service,<br>Email: <a href="mailto:Edgar.klerks@gmail.com">Edgar.klerks@gmail.com</a>,<br>
Tel: +31727851429<br>Fax: +31848363080<br>Skype: edgar.klerks<br>Website: <a href="http://flatlinerict.nl">flatlinerict.nl</a><br>Adres: Koelmalaan 258,<br>1813JD, Alkmaar<br>Nederland<br>