2016-09-10 12 views
3

現在OCamlを学びたいと思っています。そして、私はこのPythonコードの同等を探しています:OCamlの関数の引数としてリストを使う

f(*l[:n]) 

私はこの動作をエミュレートする関数を記述しようと思ったが、それは動作しません。ここでは、コードは次のようになります。

let rec arg_supply f xs n = 
    if n = 0 then 
     f 
    else 
     match xs with 
     | x :: remainder -> arg_supply (f x) remainder (n - 1);; 

そして、ここでは、私が取得エラーメッセージです:

Error: This expression has type 'a but an expression was expected of type 
'b -> 'a 
The type variable 'a occurs inside 'b -> 'a 

すべてのヘルプは高く評価され、それは私の機能の作業を取得する方法、または最初に供給するための別の方法でありますリストのn個の要素を引数として関数に渡します。

編集:nは、関数を呼び出すために必要な引数の量であり、そのため定数です。

編集:これも機能しません。

type ('a, 'r) as_value = ASFunction of ('a -> ('a, 'r) as_value) | ASReturnValue of 'r;; 

let rec _arg_supply f_or_rval xs n = 
    if n = 0 then 
     f_or_rval 
    else 
     match f_or_rval with 
     | ASFunction func -> (
      match xs with 
       | x :: r -> _arg_supply (func x) r (n - 1) 
       | _ -> failwith "too few arguments for f" 
     ) 
     | ASReturnValue out -> out;; 
+0

あなたはそれを行うことはできません。 'arg_supply'の型は' n'の実行時の値に依存しなければなりません。 – melpomene

+1

これは典型的な[XY問題](http://xyproblem.info/)です。代わりにあなたが本当にやりたいことを説明できますか? – Drup

+0

@Drup 'name_of_the_function(List.nth li 0)(List.nth li 1)(List.nth li 2)...'を書くことなく、引数がリストにある関数を呼びたいと思っています。 そして、戻り値の型がASFunctionでなければならないので、私が試した解決策がうまくいかなくても役に立ちません。しかし、私はこのタイプに合わせて機能を "拡張"することができました。 – CodenameLambda

答えて

3

あなたのPythonの関数fnの値に応じて、引数の数が渡されています。これはOCamlでは表現できません。関数は静的に固定された数の引数をとります(つまり、ソースコードを読むことによって引数の数を知ることができます)。

OCaml関数に異なる数の引数を渡す方法は、Pythonコードf(l[:n])に対応するリストを渡すことです。

(これは、OCamlの関数は一つの引数を取ると言うことは、より正確なのですが、これは別の時間のための議論である。)

更新

nが実際に一定であれば、のは、それが3だとしましょう。その後、次のような何かを行うことができます。

match l with 
| a :: b :: c :: _ -> f a b c 
| _ -> failwith "too few arguments for f" 

アップデート2

ここでは、何をしたいかを見る別の方法があります。あなたは、関数を書くのはapplyそれを呼びましょう、このように動作するにしたい:

let apply f xs = 
    . . . 

アイデアはapplyはそれをリストxsから引数を与え、機能fを呼び出すことです。

OCamlは厳密に型指定された言語なので、fの型とxsの型を指定できる必要があります。 fのタイプは何ですか? n引数の関数にしたいとします。nの長さはxsです。つまり、nは定数ではありません。しかし、OCamlにはそのような型はありません。関数型には固定された静的な数のパラメータがあります。 fのOCamlタイプはないので、関数applyを書くことはできません。一連の関数apply1apply2などを書くことができます。これらの関数のそれぞれは異なる型を持つことに注意してください。別の関数fごとに正しいものを呼び出すことを気にしないなら、それはうまくいくでしょう。

問題を解決して、OCamlの型付けに苦労するのではなく、むしろ問題を再構成することができます。私は強いタイピングに関する私のコメントがあります。強いタイピングに慣れれば、ほとんど利益をあきらめず、タイピングのサポートがほとんどない言語に戻ります。

+0

申し訳ありませんが、私はしませんでした。私の質問でそれを明確にする。 nはfに必要な引数の量であり、定数です。それは '[:n]'の理由です。 – CodenameLambda

+0

私は「n」が実際には定数であることを疑う傾向があります。さもなければ、f(* l [:3])のようなものを書くでしょう。しかし、与えられた 'n 'の値に対してコードを書くのは難しくありません。上記の**アップデート**を参照してください。 –

+0

これは、arg_supply_1、arg_supply_2、...を作成する必要があることを意味します。 これは私が実際に望むものではありません。もし私がそれらのすべてを必要としないなら、それは大丈夫でしょう。 – CodenameLambda

関連する問題