0

我有一个数据类型叫做EntrySearchableInfo这样写

type EntryDate = UTCTime -- From Data.Time

type EntryTag = Tag -- String

type EntryName = Name -- String

type EntryDescription = Description -- String

type EntryId = Int
data EntrySearchableInfo
  = SearchableEntryDate EntryDate
  | SearchableEntryTag EntryTag
  | SearchableEntryName EntryName
  | SearchableEntryDescription EntryDescription
  | SearchableEntryId EntryId

基本上代表在“搜索”上下文中有意义的事物。

我想用这种类型写一个函数

entrySearchableInfoParser :: Parser (Either String EntrySearchableInfo)

这(我认为)将是Parser <Type>我已经编写的几个原始函数的组合

entryDateParser :: Parser (Either String UTCTime)
entryDateParser = parseStringToUTCTime <$> strOption
  (long "date" <> short 'd' <> metavar "DATE" <> help entryDateParserHelp)

searchableEntryDateParser :: Parser (Either String EntrySearchableInfo)
searchableEntryDateParser = SearchableEntryDate <$$> entryDateParser -- <$$> is just (fmap . fmap)

searchableEntryTagParser :: Parser (Either String EntrySearchableInfo)
searchableEntryTagParser = ...
...

所以我有两个问题:

  1. 我如何结合这些解析器来制作entrySearchableInfoParser函数。

  2. EntrySearchableInfoEntrytype 是像这样定义的更大类型的一部分

data Entry
    = Add EntryDate EntryInfo EntryTag EntryNote EntryId
    | Replace EntrySearchableInfo Entry
    | ...
    ...

我已经有一个类型的函数

entryAdd :: Parser (Either String Entry) 

哪个构造Entry使用Add.

但我不确定如何Entry使用ReplacewithentrySearchableInfoParser和进行类型entryAdd

4

1 回答 1

0

所以结合这些解析器比我想象的要简单得多。

我只需要使用<|>

entrySearchableInfoParser :: Parser (Either String EntrySearchableInfo)
entrySearchableInfoParser =
  searchableEntryDateParser
    <|> searchableEntryTagParser
    <|> searchableEntryNameParser
    <|> searchableEntryDescriptionParser
    <|> searchableEntryIdParser

并使用with和was构造Entry类型。ReplaceentrySearchableInfoParserentryAdd

entryAdd :: Parser (Either String Entry)
entryAdd = ...

entryReplace :: Parser (Either String Entry)
entryReplace = liftA2 Edit <$> entrySearchableInfoParser <*> entryAdd

现在它完美地工作了!

于 2020-03-03T09:06:49.010 回答