2013-02-27 3 views
1

У меня есть код, который компилируется и работает. А потом некоторые, которые этого не делают. Моя забота заключалась в том, что первая версия была настолько раздутой, что она разбилась при работе с слишком большими аргументами, поэтому я написал вторую версию с учетом производительности. Вторая версия даже не компилируется. Пожалуйста посоветуй.Используйте вектор, чтобы манипулировать символами вместо списков

import System.Environment (getArgs) 
import Data.List   (nub) 
import System.Random 
import Control.Applicative ((<$>)) 
import Control.Monad  (replicateM) 

randomItem :: [a] -> IO a 
randomItem xs = (xs!!) <$> randomRIO (0, length xs - 1) 

genFromMask :: [String] -> IO String 
genFromMask = mapM randomItem 

genMeSome :: [String] -> Int -> IO [String] 
genMeSome mask n = do 
    glist <- replicateM (n*10) (genFromMask mask) 
    return $ take n $ nub glist 

writeIt :: FilePath -> Int -> [String] -> IO() 
writeIt fi n mask = do 
    glist <- genMeSome mask n 
    writeFile fi $ unlines glist 

maj :: String 
maj = ['A'..'Z'] 

numa :: String 
numa = ['0'..'9'] 


-- | Certaines regions n'utilisent aucune des plages libres 
genBra :: [String] 
genBra = ["VWXYZ",maj,maj," ",numa,numa,numa,numa] 

genAus :: [String] 
genAus = [maj,maj,maj," ",numa,numa,numa] 

main :: IO() 
main = do 
    args <- getArgs 
    case args of 
    (mo:fi:n:_) -> case mo of 
     "aus" -> writeIt fi (read n) genAus 
     "bra" -> writeIt fi (read n) genBra 
     _  -> error "country is not supported" 
    _   -> error "wrong input, format is: genLicensePlate country file number" 

А вот второй:

import System.Environment (getArgs) 
import System.Random 
import Crypto.Random.AESCtr (makeSystem) 
import Control.Applicative ((<$>)) 
import qualified Data.Vector as V 
import qualified Data.Text as T 
import qualified Data.Text.IO as T 

nubV :: V.Vector a -> V.Vector a 
nubV va 
    | V.null va    = V.empty 
    | V.any (== headV) tailV = nubV tailV 
    | otherwise    = headV `V.cons` nubV tailV 
where 
    headV = V.head va 
    tailV = V.tail va 

randomItem :: RandomGen g => g -> V.Vector a -> (a,g) 
randomItem g xs = 
    (xs V.! fst shamble, snd shamble) 
where 
    shamble = randomR (0, V.length xs - 1) g 

genFromMask :: RandomGen g => g -> V.Vector (V.Vector a) -> V.Vector a 
genFromMask g xs = 
    if V.null xs 
    then V.empty 
    else fst paket `V.cons` genFromMask (snd paket) (V.tail xs) 
where 
    paket = randomItem g (V.head xs) 

genMeSome :: RandomGen g => g -> V.Vector (V.Vector a) -> Int -> V.Vector (V.Vector a) 
genMeSome g mask n = 
    V.take n $ nubV $ V.replicateM (n*10) (genFromMask g mask) 

writeIt :: RandomGen g => g -> FilePath -> Int -> V.Vector (V.Vector a) -> IO() 
writeIt g fi n mask = 
    T.writeFile fi $ T.unlines $ T.pack $ V.toList (V.map V.toList $ genMeSome g mask n) 

maj = V.fromList ['A'..'Z'] 
num a = V.fromList ['0'..'9'] 
vspa = V.fromList " " 
vtir = V.fromList "-" 

-- | Certaines regions n'utilisent aucune des plages libres 
genBra = V.fromList [static,maj,maj,vspa,numa,numa,numa,numa] 
where 
    static = V.fromList "VWXYZ" 

genAus = V.fromList [maj,maj,maj,vspa,numa,numa,numa] 

main :: IO() 
main = do 
    g <- makeSystem 
    args <- getArgs 
    case args of 
    (mo:fi:n:_) -> case mo of 
     "aus" -> writeIt g fi (read n) genAus 
     "bra" -> writeIt g fi (read n) genBra 
     _  -> error "country is not supported" 
    _   -> error "wrong input, format is: genLicensePlate country file number" 

Я пытаюсь создать поддельные лицензии пластины, чтобы заполнить анонимную базу данных.

EDIT1:

Вот ошибки:

genLicensePlate.hs:22:12: 
    No instance for (Eq a) 
     arising from a use of `==' 
    In the first argument of `V.any', namely `(== headV) 
    In the expression: V.any (== headV) tailV 
    In a stmt of a pattern guard for 
       an equation for `nubV': 
     V.any (== headV) tailV 

genLicensePlate.hs:48:52: 
    Couldn't match expected type `Char' with actual type 
    Expected type: V.Vector Char 
     Actual type: V.Vector [a] 
    In the first argument of `V.toList', namely 
     `(V.map V.toList $ genMeSome g mask n)' 
    In the second argument of `($)', namely 
     `V.toList (V.map V.toList $ genMeSome g mask n)' 

EDIT2:

Таким образом, общая идея заключается в том, чтобы использовать маску для генерации случайных строк. Как и myFunc g [['A' .. 'Z'], ['A' .. 'Z']] дает AA или ZZ или BA или FG и т. Д. ... Затем я использую эту функцию, чтобы сделать много эти строки основаны на маске. После этого я удаляю дубликат и беру столько, сколько необходимо (так как я генерирую 10 раз число, заданное даже с дубликатом, я в порядке). Окончание Я бросаю его в файл.

Надеюсь, это станет более ясным.

С наилучшими пожеланиями, Sar

+0

Какая ошибка компиляции вы получаете? На какой линии? Также - это поможет объяснить немного больше того, что вы пытаетесь сделать. Можете ли вы написать более простую (меньшую подмножество) программу, которая имеет ту же проблему? Это вряд ли получит решение в текущей форме - очень грязное, очень локализованное (как в: «поскольку оно стоит, похоже, что вы единственный, у кого когда-либо будет эта проблема», что делает его плохим вопросом SO, как правило) – Floris

+1

Если вы обеспокоены производительностью, вы не должны использовать алгоритм 'Ω (n²)' для удаления дубликатов в наборе, когда вы можете сделать это в 'O (n log n)' –

+0

Я пытаюсь сделать функцию которые генерируют String или Text из маски любое заданное количество времени. [['0' .. '9'], ['0' .. '9']] может дать мне любое двухзначное число, например, «56» или «78». Что касается функции nub, у вас есть идея. Как я уже сказал, код разбился при попытке создать много строк, поэтому мне нужно, чтобы он не разбился. – Sarfraz

ответ

3

nubV нужно Eq ограничения, так как он сравнивает элементы (но вы действительно должны использовать Set или HashSet или так, чтобы получить лучший алгоритм)

nubV :: Eq a => V.Vector a -> V.Vector a 
nubV va 
    | V.null va    = V.empty 
    | V.any (== headV) tailV = nubV tailV 
    | otherwise    = headV `V.cons` nubV tailV 
where 
    headV = V.head va 
    tailV = V.tail va 

И в writeIt, вам не хватает map,

writeIt :: RandomGen g => g -> FilePath -> Int -> V.Vector (V.Vector a) -> IO() 
writeIt g fi n mask = 
    T.writeFile fi $ T.unlines $ map T.pack $ V.toList (V.map V.toList $ genMeSome g mask n) 
          -- ^^^ 

, так как вы получаете список списков Char от V.toList (V.map V.toList $ genMeSome g mask n).

Это исправление двух сообщенных ошибок.

Смежные вопросы