2016-03-09 2 views
0

Привет Я пытаюсь преобразовать эту строкуПреобразование строки в пользовательский тип Haskell

Blade Runner,Ridley Scott,1982,Amy,5,Bill,8,Ian,7,Kevin,9,Emma,4,Sam,7,Megan,4​ 

к типу пленки

type UserRatings = (String,Int) 
type Film = (Title, Director, Year , [UserRatings]) 

из текстового файла, который содержит 25 фильмов

это что я пытался сделать

maybeReadTup :: String ->(String, Int) 
maybeReadTup s = do 
    [(n, [c])] <- return $ reads s 
    return [(n, [c])] 

    parseLines :: [String] -> Film 
    parseLines list 
      | isInt(list !! 3) = (list !! 0,(list !! 1), read (list !! 2), maybeReadTup [ (list!!1,read (list !! 2))]) 

isInt :: String ->Bool 
isInt[] = True 
isInt (x:xs) 
    | isNumber x = True && isInt xs 
    | otherwise = False 

parseChars :: String -> String -> [String] 
parseChars [] _ = [] 
parseChars (x:xs) stringCount 
    | x == ',' = [stringCount] ++ parseChars xs "" 
    | otherwise = (parseChars xs (stringCount ++ [x])) 

parseAll :: [String] -> [Film] 
parseAll [] = [] 
parseAll (x:xs) = parseLines (parseChars x "") : (parseAll xs) 

Но я ошибаюсь, может кто-то может помочь мне разобрать этот пользовательский тип tuple [(String,Int)]? И можете ли вы помочь мне понять, как работают parseLines? Я новичок в Haskell

+0

Почему каждое слово на входе через запятую? – chepner

+0

@chepner есть лучший способ сделать это? Если я изменю файл, это поможет мне разобрать его? – Max

+0

Я бы предположил, что что-то вроде «Blade Runner, Ridley Scott, 1982, ...» было бы лучше, чтобы вы знали, где заканчивается название и начинается режиссер (при условии, конечно, что названия не содержат * запятые). – chepner

ответ

2

Вот решение, использующее Text.Parsec:

import   Text.Parsec 
import   Text.Parsec.String 

type UserRatings = (String, Int) 
type Title = String 
type Director = String 
type Year = Int 
type Film = (Title, Director, Year, [UserRatings]) 

str :: Parser String 
str = many1 (noneOf ",") 

int :: Parser Int 
int = read <$> many1 digit 

tup :: Parser UserRatings 
tup = do user <- str 
     _ <- oneOf "," 
     rating <- int 
     return (user, rating) 

parser :: Parser Film 
parser = do title <- str 
      _ <- oneOf "," 
      director <- str 
      _ <- oneOf "," 
      year <- int 
      _ <- oneOf "," 
      ratings <- sepBy tup (oneOf ",") 
      eof 
      return (title, director, year, ratings) 

testString :: String 
testString = "Blade Runner,Ridley Scott,1982,Amy,5,Bill,8,Ian,7,Kevin,9,Emma,4,Sam,7,Megan,4" 

main :: IO() 
main = print $ runParser parser() "testString" testString 
+0

У меня есть база данных, хотя «testString» бесполезен для меня, как я могу исправить этот код здесь, чтобы поместить мою базу данных в парсер? 'главная :: IO() основные = у tempDatabase <- ReadFile "films.txt" Пусть I = линия tempDatabase пусть база данных = runParser анализатора() базы данных putStrLn "Введите ваше имя:" имени пользователя <- GetLine userInterface database username appendFile "films.txt" (показать базу) putStrLn "Ваши изменения в базе данных были успешно сохранены." ' – Max

+0

Вызов текстового файла, база данных немного растянута. 'filmList <- map (runParser parser() fileName) <$> строки <$> readFile fileName' должен работать. – obadz

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