2017-11-16 5 views
3

可変量のパラメータを取り込む関数を作成しようとしていますが、F#の実行可能な解を見つけることができません。Fsharp:関数のNパラメータを渡す

let expression = (fun a b -> a || b) 
let expressionTriple = (fun a b c -> (a || b) && c) 

// This doesn't work because expression can either be a function that takes fixed arguments 
let truthTable numPredicates expression = 
    if numPredicates = 2 then 
     expression true true 
    else 
     expression true true false 


truthTable 2 expression 
truthTable 3 expressionTriple 

どのように表現関数にさまざまな引数を渡すことができますか?

+0

「truthTable 3 expression」に何をしますか? – Lee

+0

truthTable 3は、渡す述語の数を示します。 – rudresh4

+0

はい、 'expression'は2つの引数しか取らないので、' expression true true false'は通常はコンパイルエラーです。 – Lee

答えて

3

F#では、異なるシグネチャ(異なる数のパラメータを含む)を持つ関数は異なる型と見なされます。また、関数に2つの異なる型(または12種類の異なる型)を指定できるようにするには、discriminated unionsを使用する必要があります。ちょうどその区別組合にQuad of ('a -> 'a -> 'a -> 'a -> 'a)ケースを追加し、あなたは4パラメータのバージョンを追加したい場合は

type Expression<'a> = 
    | Double of ('a -> 'a -> 'a) 
    | Triple of ('a -> 'a -> 'a -> 'a) 

let expression = fun a b -> a || b 
let expressionTriple = fun a b c -> (a || b) && c 

// This works because expression is a discriminated union 
let truthTable expression = 
    match expression with 
    | Double f -> f true true 
    | Triple f -> f true true false 

truthTable (Double expression) 
truthTable (Triple expressionTriple) 

:ここでは、コンパイルして、あなたが何をしようとして行うような方法で、あなたのコードを書くことができる方法です、 等々。

boolではなくgenericタイプ'aでこれを書いたようなご質問がある場合は、お気軽にフォローアップの質問をしてください。

+0

他のオプションはオーバーロードですが、任意の真理値表をモデル化するためにオーバーロードを使用しません。それは単に正しく感じられません。 – Gustavo

+0

これを任意のNパラメータに拡張する方法はありますか?私の現在の回避策は、ParamArrayを使用することです。https://github.com/rudresh4/discite/blob/52c95bf507b2b706ffeb24277c384ec57477667e/fsharp/99-problems/48-logical-expression/LogicalExpressionTest.fs#L28 – rudresh4

+0

私はGithubリポジトリから、 99個の問題を処理しています。これは問題48です。これまでに私が見た唯一の解決策は、 'expression'をリストを取る関数にすることでした。たとえば、http://www.fssnip.net/ar/title/NinetyNine-F-Problems-Problems-46-50-Logic-and-Codesの問題文は、呼び出すことができる関数 'tablen'を定義することを望んでいます'tablen 3(fun [a; b; c] - > a &&(b || c)= a && b || a && c)'のようになります。あなたの 'ParamArray'ソリューションはそれほど離れているわけではありません。 – rmunn

2
let expression = (fun [a; b] -> a || b) 
let expressionTriple = (fun [a; b; c] -> (a || b) && c) 

let truthTable numPredicates expression = 
    if numPredicates = 2 then 
     expression [true; true] 
    else 
     expression [true; true; false] 


truthTable 2 expression 
truthTable 3 expressionTriple 
+0

これは動作しますが、最初の2行で警告が生成されます。 – Soldalma

関連する問題