2016-08-10 6 views
2

現在、いくつかのエクササイズをexercism.ioから行っています。 1つのエクササイズは、シーケンス内のすべての数字を合計し、異なるシーケンスからの1つ以上の数字の倍数です。小さな機能に問題を分割することは良いアイデアのように思えたし、私はこの思い付いた:パラメータの順序を変更しないようにする方法

let multipleOf m n = 
    n % m = 0 

let anyMultipleOf (m: int list) n = 
    m 
    |> Seq.exists (multipleOf n) 

let sumOfMultiples m n = 
    [1..n-1] 
    |> Seq.filter (anyMultipleOf m) 
    |> Seq.sum 

アイデアので、私は私の(any)multipleOf関数にmパラメータ「で焼く」する部分のアプリケーションを使用することができます。しかし、Seq.exists (multipleOf n)は実際にnを私のmパラメータとして適用しているので、このコードは私が望むようには機能しません。

multipleOf関数のパラメータの順序を逆にする必要なくこのコードをリファクタリングするにはどうすればよいですか?


注:私は私のanyMultipleOf関数の中で私のmultipleOf機能を使用するソリューションを求めています。このソリューションは動作しますが、私の最初の関数を再利用していない:

let anyMultipleOf (m: int list) n = 
    m 
    |> Seq.exists (fun x -> n % x = 0) 
+1

'multipleOf'と' anyMultipleOf'の両方が実際には逆の順序でパラメータを持つべきです。パラメータは、より一般的なものからより具体的なものへと定義される。 '(any)MultipleOf x'を現在の方法よりも再利用することがポイントです。 – Sehnsucht

+1

私の思考プロセスはまったく逆でした。 'let anyMultipleOfMyNumbers = anyMultipleOf [3; 5; 7]' –

+0

これもうまくいきます: 'let filterMultiplesOf5 numlist = numlist |> Seq.filter(multipleOf 5)' –

答えて

4

flipを使用するように提案してタイプでしたが、行うには明白なことはこれです:

let anyMultipleOf (m: int list) n = 
    m 
    |> Seq.exists (fun x -> multipleOf x n) 

flipが持っている便利なツールですが、反転した機能のパイプラインが読み痛いです。

+0

Whileそれはフリップと同じです、私はあなたのソリューションが良いのが好きです。それはパラメータがどこに行くかをより明示的に示し、さらに多くのパラメータを持つときに読みやすくなります。 –

2

あなたがあなた自身にだけ行うことを関数を定義することができます
は逆の順序で機能し、2つの引数をとり、引数を適用した結果を返しますがあなたが最後の引数としてリストを取るためにanyMultipleOfを再定義していない理由、それは私には不明ですが機能に右の順に

let flip f y x = f x y 
3

、いつでも使用することができflip

let flip f x y = f y x 

この機能はexists in Haskellですが、FSharp.Coreにはありません。これはあなた自身で定義する必要がある理由です。

例として、flip anyMultipleOfは、タイプがint -> int list -> boolの関数を返します。これは、質問を正しく理解すれば、あなたが望むものです。

関連する問題