了解 Haskell 流行的 optparse-applicative 库的介绍性代码片段

Understanding the introductory code snippet for Haskell's popular optparse-applicative library

来自流行 optparse 库的介绍性代码片段:

data Sample = Sample
  { hello :: String
  , quiet :: Bool }

sample :: Parser Sample
sample = Sample
  <$> strOption -- Q1
      ( long "hello"
     <> metavar "TARGET" -- Q2
     <> help "Target for the greeting" )
  <*> switch
      ( long "quiet"
     <> help "Whether to be quiet" )

查看我的 questions/confusion 代码片段中的注释。

Q1:<$>如何作为类型构造函数Sample的第一个参数?我以为这个操作必须用在函数和仿函数之间。

问题 2:此代码段中使用的操作 <> 是什么?

Q1: How is it that <$> can be used as the first argument of the type constructor Sample? I thought this operation had to be used between a function and a functor.

恰恰相反:Sample(<$>) 的第一个参数,它被映射到 strOption 产生的 Parser String 上。

Q2: What is the operation <> used throughout this code snippet?

(<>)mappend 的同义词,来自 Monoid class。在这种情况下,它用于将各个设置组合到一组设置中,以用于您正在定义的每个命令行选项。

使用ApplicativeDoNamedFieldPuns扩展,也可以这样写:

{-# language ApplicativeDo #-}
{-# language NamedFieldPuns #-}
import Options.Applicative
import Data.Monoid

data Sample = Sample
  { hello :: String
  , quiet :: Bool }

sample :: Parser Sample
sample = do
    hello <- strOption ( long "hello"
                      <> metavar "TARGET"
                      <> help "Target for the greeting" )
    quiet <- switch ( long "quiet"
                   <> help "Whether to be quiet" )
    pure (Sample {hello,quiet})