1

RamDA.jsを使用して、ポイントフリーの手法を使用して私のオリジナルの解をgetPermutations()関数にリファクタリングしようとしています。それをリファクタリングすることは、ポイントフリーのスタイルに向けてさらに可能ですか?私はちょうどさらに大きな混乱を作りました。また、現在、テストを実行するときにリファクタリングされたバージョンにバグがあります。TypeError:reduce:listは配列または反復可能でなければなりません。再帰、Ramda.jsおよびポイントフリースタイルを使用してStringのgetPermutations()をリファクタリングします。

オリジナルソリューション:Ramda.jsをリファクタリングする

// getPermutations :: String -> [String] 
function getPermutations(string) { 
    function permute(combination, permutations, s) { 
    if (!s.length) { 
     return permutations[combination] = true; 
    } 

    for (var i = 0; i < s.length; i++) { 
     permute(combination.concat(s[i]) 
      , permutations 
      , (s.slice(0, i) + s.slice(i+1)) 
      ); 
    } 
    return Object.keys(permutations); 
    } 

    return permute('', {}, string); 
} 

私の試み:

var _ = require('ramda'); 

// permute :: String -> {String: Boolean} -> String -> [String] 
var permute = _.curry(function (combination, permutations, string) { 
    // callPermute :: String -> ({String: Bool} -> Char -> Int -> String) -> IO 
    var callPermute = function (combination) { 
    return function (acc, item, i, s) { 
     return permute(_.concat(combination, item) 
        , acc 
        , _.concat(_.slice(0, i, s), _.slice(i + Infinity, s)) 
        ); 
    }; 
    }; 

    var storeCombination = function() { 
    return permutations[combination] = true; 
    }; 

    // should be an ifElse, incorporating compose below 
    _.when(_.not(string.length), storeCombination); 

    return _.compose(_.keys 
        , _.addIndex(_.reduce(callPermute(''), {})) 
       ) (string.split('')); 
}); 

// getPermutations :: String -> [String] 
var getPermutations = permute('', {}); 
+0

どういうところですか? point-freeスタイルで 'permute'関数を書くだけですか?それは非常に難しいです。 –

+0

@AaditMShah、それは正しいです。私はpoint-freeスタイルで 'permute'関数を書くことを望んでいました。あなたのフィードバックは役に立ちます。私は何かシンプルなものを見逃していたかどうか、問題を間違って/サブ最適に見ているのか、再帰関数がポイントフリーのスタイルにリファクタリングするのが本質的に難しいのか分かりませんでした。フィードバックをお寄せいただきありがとうございます! – Eric

+0

私は、ポイントフリーのリファクタリング、特に固定小数点のコンビネータに頼らずにポイントフリーの再帰を達成することは難しいことによく同意します。しかし、私は、この質問が、ポイントフリーではなく、図書館に言及せず、既存のコードのリファクタリングについて話をしなかった、リンクされた質問の複製として閉じられるべきであることに同意しません。彼らは両方ともJSの置換関数を求めていました。それはそれらが重複することはありません。 –

答えて

0

あり、あなたのソリューションにはいくつかの問題であるように見える、と私は私が持っていない怖いですそれらを追いかける時間。 (私が見る最初の事はあなたが間違ってaddIndexを使用していることである)

しかし、しばらく前I wrote this、あなたはRAMDAで働いpermutation機能を確認したい場合:

// permutations :: [a] -> [[a]] 
const permutations = (tokens, subperms = [[]]) => 
    R.isEmpty(tokens) ? 
    subperms : 
    R.addIndex(R.chain)((token, idx) => permutations(
     R.remove(idx, 1, tokens), 
     R.map(R.append(token), subperms) 
    ), tokens); 

R.map(R.join(''), permutations(['A', 'B', 'C'])); 
//=> ["ABC", "ACB", "BAC", "BCA", "CAB", "CBA"] 

(あなたがこれで遊ぶことができますRamda REPL

+0

あなたのソリューションは、OPが望んでいたならば、ポイントフリーではありません。 –

+0

@ScottSauyet、 'addIndex'についてのヒントをありがとう。なぜそれが動作していなかったのか、私は本当に混乱していました。そしてポイントフリーではありませんが、私は本当にあなたのソリューションを掘り下げています。私はポイントフリーにしようとばかげた運動を試みてきたように思えるかもしれない。私は私のリファクタが近くにいないことを知っていますが、私は少なくとも助けを求める前に私の試みを示したかったのです。ほとんどの再帰関数は、本質的にポイントフリーのスタイルで記述するのが難しいのですか? – Eric

+0

@エリックすべての機能をポイントフリーのバージョンに変換することができます。しかし、それはすべての機能がすべきことを意味するものではありません。ポイントフリーの関数は、[η変換](https://en.wikipedia.org/wiki/Lambda_calculus#.CE.B7-conversion)や[関数の構成](https://en.wikipedia .org/wiki/Function_composition)。他のほとんどの場合、目立つ関数は読みやすくなります。 pointfulな表現をpoint-freeの表現に変換する[アルゴリズム](https://en.wikipedia.org/wiki/Combinatory_logic#Completeness_of_the_S-K_basis)があります。 –

関連する問題