2016-03-09 114 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) 

但我得到错误的类型可以有人请帮我解析这个UserRatings元组类型[(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” 让我=行tempDatabase 让数据库= runParser解析器()数据库 putStrLn “输入您的姓名:” 用户名< - 函数getline userInterface数据库用户名 appendFile“films.txt”(显示数据库) putStrLn“您对数据库的更改已成功保存。” – Max

+0

调用数据库的文本文件有点夸张。 'filmList < - map(runParser parser()fileName)<$> lines <$> readFile fileName' should be working。 – obadz

相关问题