1

これは、この質問の延長です。

Haskellでコマンドライン引数を使用して正しい関数にディスパッチする

そのため、コマンドラインから他の関数​​に「コマンド」をディスパッチするための適切な解決策はまだありません。そこで、上記の質問のアプローチを拡張したいと思います。テーブルに手動で関数を追加し、適切な変換関数を各関数に適用して、通常の引数の代わりに正しいサイズのリストを取得する必要があるのは面倒です。代わりに、関数を追加し、コマンド ラインから取得する必要がある引数の数を「タグ付け」するテーブルを作成したいと思います。次に、「add」プロシージャは、正しい「takesXarguments」プロシージャを使用して構成し、それをテーブルに追加する必要があります。

関数の「パッケージ」をテーブルにインストールできるようにしたいのですが、パッケージがインストールされるとテーブルの状態が変化するため、テーブルの状態を追跡できる必要があると思います。Reader モナドまたは State モナドは私が探しているものですか?

4

1 に答える 1

1

モナドは必要ありません。タグ付けのアイデアは正しい方向に進んでいますが、その情報はおそらく予想とは異なる方法でエンコードされています。

コマンドの定義から始めます。

type Command = [String] -> IO ()

次に、「コマンドメーカー」機能を作成できます。

mkCommand1 :: (String -> IO ()) -> Command
mkCommand2 :: (String -> String -> IO ()) -> Command
...

タグとして機能するもの。関数の急増が気に入らない場合は、「コマンド ラムダ」を作成することもできます。

arg :: (String -> Command) -> Command
arg f (x:xs) = f x xs
arg f [] = fail "Wrong number of arguments"

次のようなコマンドを記述できるようにします。

printHelloName :: Command
printHelloName = arg $ \first -> arg $ \last -> do
    putStrLn $ "Hello, Mr(s). " ++ last
    putStrLn $ "May I call you " ++ first ++ "?"

もちろんmkCommand1、etc. は , という言葉で簡単に書くことができarg、両方の長所を活かすことができます。

パッケージに関しては、Command複数のサブコマンド間の選択肢を十分にカプセル化しますが、それらは構成しません。ここでの 1 つのオプションは、次のように変更Commandすることです。

type Command = [String] -> Maybe (IO ())

これにより、返されCommandない最初のアクションを実行することで、複数の を単一のに構成できますNothing。これで、パッケージも型の値にすぎませんCommand。(一般に、Haskell では、これらの構成に非常に関心があります。パッケージやリストではなく、2 つのオブジェクトを使用して複合オブジェクトを作成する方法を考えてください)

(1) 関数が取る引数の数を検出する合理的な方法がなく*、(2) 型を数値に依存させる方法がないため、mkCommand最初の引数として引数の数の an を取るa を作成することはできませんInt

これが役に立ったことを願っています。

  • この場合、あることがわかりましたが、私はそれをやめることをお勧めします。それは悪い習慣だと思います。物事がより抽象的になると、テクニックは機能しなくなります。しかし、私は純粋主義者です。ダクトテープのような Haskellers が私に反対するかもしれません。
于 2012-04-07T08:53:58.443 に答える