[英]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.