簡體   English   中英

Haskell 命令行選項

[英]Haskell command line options

我編寫了一個從 stdIn 讀取的基本頭模擬器:

import IO
import System

io lineList = interact (unlines . lineList . lines)
--Found this. Basically it takes all input from stdIn and reads it lazily.
main = do
    [numLines] <- getArgs
    io (take (read numLines))
    --reads by lines.

然后我嘗試像這樣添加命令行(來源: http://leiffrenzel.de/papers/commandline-options-in-haskell.html

import IO
import System
import System.Console.GetOpt

io lineList = interact (unlines . lineList . lines)
--Found this. Basically it takes all input from stdIn and reads it lazily.
main = do
    args <- getArgs
    let ( actions, nonOpts, msgs ) = getOpt     RequireOrder     options args
    opts <- foldl (>>=) (return defaultOptions) actions
    let Options {   optNum = input,
                    optOut = output} = opts
    input >>= output

data Options = Options {
        optNum :: IO String,
        optOut :: String -> IO ()
    }

defaultOptions :: Options
defaultOptions = Options {
        optNum = "10",
        optOut = io (take optNum)
    }

options :: [OptDescr (Options -> IO Options)]
options = [
    Option ['n'] ["numlines"] (OptArg readNumLines     )    "read x amount of lines"
    ]

readNumLines arg opt = return opt (go arg)
go w = io (take (read w))
    --reads by lines.

現在,我在這里的經驗已經不多了。 如果設置了 N 開關,我實際上調用 readNumLines 的唯一地方似乎是選項。 現在,如果未設置 N 開關,我想運行 arg 為 10 的 readNumLines 命令。我顯然沒有這樣做。

提前致謝:)

編輯:因此,在對我的代碼進行了一些拖釣之后,我將它放到了 state 中,它不會向我拋出任何錯誤,但仍然無法編譯:不在 scope 中:數據構造函數“選項”,但我'已經定義了選項? 編輯:我已經更改了 Options 構造函數,但現在它告訴我它無法將 IO Options 的預期類型與 opts <- foldl (>>=) (return defaultOptions) 操作中的實際類型 Options 匹配

我嘗試刪除操作,但沒有奏效。

編輯:所以我刪除了大部分有問題的行,它起作用了。

opts <- 返回默認選項

但是,傳遞 -n 不會做任何事情,它只返回前 10 行。

讓我們來看看 main 的main應該做什么。

讀取命令行 arguments:
args <- getArgs

解析 arguments:
let ( actions, nonOpts, msgs ) = getOpt RequireOrder options args

將arguments組合成一組程序參數:
opts <- foldl (>>=) (return defaultOptions) actions

提取參數:
let Options { optNum = input, optOut = output} = opts

使用參數:
input >>= output

GetOpt 庫僅處理解析命令行 arguments。 在您的情況下,命令行 arguments 唯一可以控制的是 output 的行數,因此 Options 數據結構應該只包含 output 的行數。 將其編碼為字符串沒有意義,您可以使用 int。

data Options = Options { optNum :: Int }

當您指定命令行選項時, ArgDescr用於指定選項參數的解析器。 解析器接受一個字符串並將其轉換為特定於程序的數據結構。 您想要的是將字符串轉換為更新 Options value 的 function 請注意,我取出了 IO 類型(您不需要 IO),這將需要在代碼的其他地方進行一些小的更改。

readNumLines :: String -> Options -> Options
readNumLines n options = options {optNum = read n}

解析選項后,默認選項會按照每個命令行參數的指示進行更新(請記住,解析會生成更新選項值的函數),以生成最終選項。 您正在使用 IO 執行此步驟,但您確實不需要。
opts <- foldl (>>=) (return defaultOptions) actions

由於Options的字段已更改,因此 main 中的選項提取代碼必須更新為
let Options { optNum = opt_num } = opts

此時,您有一個變量,該變量根據命令行選項保存應打印的實際代碼行數,您可以使用它做任何您想做的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM