2016-07-09 8 views
1

ファイルを読み込んで処理し、結果を別のファイルに書きたい。入力ファイル名はコンソール引数で指定し、出力ファイル名は入力ファイル名から生成します。ハスケルの条件付きハンドルリダイレクト

引数が指定されていない場合、stdin/stdoutに透過的に "フェイルオーバー"したいです。基本的にファイル名が指定されている場合はstdin/stdoutをそれぞれのファイル名にリダイレクトして、透過的に使用できるようにしますファイル名が指定されているかどうか。

ダミー出力と一緒にハックされたコードは、余分な以外ににあります。それを行うための適切な、慣用的な形式は何でしょうか?

それはおそらく同様の質問で指摘し、多分誰かがすでにこれを書いたとして、Control.Monadのまたはガードとは何かを持っている可能性があります。

import System.IO 
import Data.Char(toUpper) 
import System.Environment 
import GHC.IO.Handle 

main :: IO() 
main = do 
     args <- getArgs 
     if(not $ null args) then 
     do 
      print $ "working with "++ (head args) 
      finHandle <- openFile (head args) ReadMode --open the supplied input file 
      hDuplicateTo finHandle stdin --bind stdin to finName's handle 
      foutHandle <- openFile ((head args) ++ ".out") WriteMode --open the output file for writing 
      hDuplicateTo foutHandle stdout --bind stdout to the outgoing file 
     else print "working through stdin/redirect" --get to know 
     interact ((++) "Here you go---\n" . map toUpper) 

答えて

1

についてinteract非常に特別なものは何もありません - ここでは、その定義です:

interact  :: (String -> String) -> IO() 
interact f  = do s <- getContents 
         putStr (f s) 

このようなものについてはどのように:

import System.Environment 
import Data.Char 

main = do 
    args <- getArgs 
    let (reader, writer) = 
     case args of 
      []   -> (getContents, putStr) 
      (path : _) -> let outpath = path ++ ".output" 
         in (readFile path, writeFile outpath) 
    contents <- reader 
    writer (process contents) 

process :: String -> String 
process = (++) "Here you go---\n" . map toUpper 

我々はreaderwriterを設定し、コマンドライン引数に基づいて、入力を読み取って出力を書き込むIOアクションに渡します。

+0

は'相互作用を脱糖いただき、誠にありがとうございますこのコードは確かに手元の問題を解決し、移植性も向上しました( 'hDuplicateTo'はGHC特有であり、2010年のHaskellレポートにはありません)。 – yvs314

1

これはすでに私にとってかなり慣れているようです。私が持っている1つのノートは、安全でない関数(実行時エラーを投げる可能性がある)であるので、headを避けることです。この場合は、caseを使用してパターンマッチングを行うことにより、かなり簡単です。

main :: IO() 
main = do 
    args <- getArgs 
    case args of 
    fname:_ -> do 
     print $ "working with " ++ fname 
     finHandle <- openFile fname ReadMode 
     hDuplicateTo finHandle stdin 
     foutHandle <- openFile (fname ++ ".out") WriteMode 
     hDuplicateTo foutHandle stdout 
    [] -> do 
     print "working through stdin/redirect" 
    interact ((++) "Here you go---\n" . map toUpper) 
+0

作品は私に** NOP **操作のちょうど一種である標準入力/ redirect'を通じて作業 'プリント」は、質問は、私は完全にそれを回避する方法にあったが。 – yvs314