使用optparse-applicative创建“可选”解析器并为递归数据类型构造值

时间:2020-03-03 06:52:21

标签: haskell optparse-applicative

我有一个这样写的名为var result = (from e in DSE.employees join d in DSE.departments on e.department_id equals d.department_id join ws in DSE.workingshifts on e.shift_id equals ws.shift_id select new { FirstName = e.FirstName, LastName = e.LastName, Gender = e.Gender, Salary = e.Salary, Department_id = e.department_id, Department_Name = d.department_name, Shift_id = ws.shift_id, Duration = ws.duration, }).ToList(); // TODO utilize the above result 的数据类型

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>

所以我有两个问题:

  1. 我如何组合这些解析器以实现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 = ... ... 函数。

  2. entrySearchableInfoParser类型是这样定义的较大EntrySearchableInfo类型的一部分

Entry

我已经有一个类型为

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

使用entryAdd :: Parser (Either String Entry) 构造Entry

但是我不确定如何将AddEntryReplace一起使用entrySearchableInfoParser

1 个答案:

答案 0 :(得分:0)

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

我只需要使用<|>

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

也可以使用EntryReplaceentrySearchableInfoParser来构造entryAdd类型。

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

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

现在可以正常使用了!