了解 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。在这种情况下,它用于将各个设置组合到一组设置中,以用于您正在定义的每个命令行选项。
使用ApplicativeDo
和NamedFieldPuns
扩展,也可以这样写:
{-# 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})
来自流行 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。在这种情况下,它用于将各个设置组合到一组设置中,以用于您正在定义的每个命令行选项。
使用ApplicativeDo
和NamedFieldPuns
扩展,也可以这样写:
{-# 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})