2

나는 다음과 같은 유형 및 파서가있는 경우 :하스켈 optparse의-실용적 : 여러 필드를 레코드 목록을 구문 분석

data Mode = 
    Mode1 
    | Mode2 
    deriving (Show, Eq, Read) 

data ThingINeedMulitpleOf = 
    Thing { _name :: String, _mode :: Mode } 
    deriving (Show, Eq) 

thingParser :: Parser ThingINeedMulitpleOf 
thingParser = Thing <$> strArgument (metavar "NAME") 
        <*> option auto (long "mode" <> metavar "MODE") 

을 나는 다음과 같은 방법으로 파서 구축 :

data Config = 
    Config ThingINeedMulitpleOf ThingINeedMulitpleOf 
    deriving (Show, Eq) 

loadConfig = execParser $ info (Config <$> thingParser <*> thingParser) fullDesc 

을 그럼 난 성공적으로 my-exe Thing1 --mode Mode1 Thing2 --mode Mode2을 구문 분석 할 수 있지만 정확히 두 가지만 원할 경우에만 유용합니다 Things. NThing의를 지원하기 위해 Config을 변경하려고 할 때 내가 문제로 실행 해요 예 :

data Config = 
    Config [ThingINeedMulitpleOf] 
    deriving (Show, Eq) 

loadConfig = execParser $ info (Config <$> many thingParser) fullDesc 

하지만 난 이제 더 이상 흥미롭게도 나에게 오류 Invalid argument 'Thing1'

을 제공 my-exe Thing1 --mode Mode1 Thing2 --mode Mode2 구문 분석 할 수 없습니다, ThingINeedMulitpleOf에 필드가 하나만있는 경우이 방법이 적용됩니다.

답변

3

Alternative 함수를 사용하여 서브 클래스를 사용하는 경우에는 약간 다른 명령 줄 구문을 사용하여 원하는 효과를 얻을 수 있습니다. 이와

thingSubparser :: Parser ThingINeedMulitpleOf 
thingSubparser = subparser $ command "thing" (info thingParser mempty) 

loadConfig :: IO Config 
loadConfig = execParser $ info (Config <$> some thingSubparser) fullDesc 

이 같은 명령 줄 쓸 수 있습니다 다음 구성 개체를 얻을 수

my-exe thing test --mode Mode1 thing test2 --mode Mode2 

: 당신이 할 수 subparser을 필요로하는 이유

Config [Thing {_name = "test", _mode = Mode1},Thing {_name = "test2", _mode = Mode2}] 

내가 아주 확실하지 않다 '를 그냥 thingParser에 대해 some을 사용하십시오. 그러나 명령이 파서에게 구분 기호 ("thing"인수/명령 이름)를 제공하기 때문에 그럴 것 같았 으면합니다.

관련 문제