【问题标题】:Convert a String to Custom Type Haskell [duplicate]将字符串转换为自定义类型 Haskell [重复]
【发布时间】:2016-03-09 14:08:01
【问题描述】:

您好,我正在尝试转换此字符串

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 的新手

【问题讨论】:

  • 为什么输入中的每个单词都用逗号分隔?
  • @chepner 有没有更好的方法来做到这一点?如果我更改文件,它会帮助我解析它吗?
  • 我想像Blade Runner,Ridley Scott,1982,... 这样的东西会更好,这样你就知道标题在哪里结束,导演从哪里开始(当然,假设标题不包含 逗号)。
  • @chepner 你说得对,我就是这样,这是一个拼写错误,你知道我该怎么做吗?
  • 1.请编译您的文件或提供您无法理解的错误消息,2. 问一个有意义的问题 - “我得到错误的类型”不够具体,3. parseLines 的缩进错误,4. 你没有定义一切——作者、标题、年份都不见了——我能猜到。但是,在发布问题时,请至少表现出您期望有人回复您的努力。对您的问题“有人可以帮助我”的有效但完全没有帮助的答案是“是”。

标签: parsing haskell tuples


【解决方案1】:

这是使用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

【讨论】:

  • 我有一个数据库,所以“testString”对我来说毫无用处,我如何在此处修复此代码以将我的数据库放入解析器? main :: IO () main = do tempDatabase &lt;- readFile "films.txt" let i = lines tempDatabase let database = runParser parser () database putStrLn "Enter your name: " username &lt;- getLine userInterface database username appendFile "films.txt" (show database) putStrLn "Your changes to the database have been successfully saved."
  • 将文本文件称为数据库有点牵强。 filmList &lt;- map (runParser parser () fileName) &lt;$&gt; lines &lt;$&gt; readFile fileName 应该可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-27
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 2017-06-22
  • 2020-03-17
相关资源
最近更新 更多