3

次の Haskell コードがあるとします。

data Option
    = Help
    | Opt1 Int Double String
    -- more options would be here in a real case

handleOption :: Option -> IO ()
handleOption option = case option of
    Help -> handleHelp
    Opt1 n f s -> handleOpt1 n f s

handleHelp :: IO ()
handleHelp = print "help"

handleOpt1 :: Int -> Double -> String -> IO ()
handleOpt1 n f s = print (n, f, s)

上記のコードでは、データをきちんとまとめておくことができるという意味で、事前にオブジェクトを分解するのはもったいないように思えます。ここで、Opt1 の各部分を個別に渡すか、単一の個別のデータ型を作成してそれらを運ぶ必要があります。コンパイルエラーを起こすなど、一般的なインスタンスを渡すことを許可せずに全体を渡すことはOpt1できますか?handleOpt1OptionhandleOpt1 Help

以下の疑似コードの例:


data Option
    = Help
    | Opt1 Int Double String

handleOption :: Option -> IO ()
handleOption option = case option of
    Help -> handleHelp
    opt1 @ Opt1{} -> handleOpt1 opt1

handleHelp :: IO ()
handleHelp = print "help"

handleOpt1 :: Option:Opt1 -> IO ()
handleOpt1 (Opt1 n f s) = print (n, f, s)
4

4 に答える 4

2

この特定の例では、「問題」を捨てhandleHelpて、それらを関数handleOpt1の別々の方程式にすることで解決する方がはるかに自然に思えます。handleOption

handleOption :: Option -> IO ()

handleOption Help = print "help"

handleOption (Opt1 n f s) = print (n, f, s)

これにより、両方の長所が得られます。ケースごとに個別の方程式を書くことができます(したがって、各ケースが大きくても、それらが単一の巨大な方程式に溶け込まないようにすることができます)、ボイラープレートの「ディスパッチ」関数を記述する必要はありません。Opt1実際に使用する必要があるまで、ケースの部品に名前を付けます。

于 2013-04-20T01:04:30.623 に答える