1

Я пытаюсь реорганизовать свое исходное решение на функцию getPermutations(), используя точечный подход с использованием Ramda.js. Можно ли реорганизовать его дальше, в сторону бесшумного стиля. Похоже, я просто сделал еще больший беспорядок. Кроме того, при запуске тестов в исправленной версии есть ошибка: TypeError: reduce: list должен быть массивом или итерируемым.Рефакторинг 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); 
} 

Моя попытка реорганизовать с Ramda.js:

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

На ваш вопрос? Вы просто хотите написать функцию 'permute' в стиле point-free? Это очень сложно. –

+0

@AaditMShah, это правильно. Я надеялся написать функцию 'permute' в стиле point-free. Ваши отзывы помогают. Я не был уверен, что я пропустил что-то простое, неправильно рассмотрев проблему/не оптимально, или если рекурсивные функции по своей сути трудно реорганизовать в бесконтактный стиль. Спасибо за ответ! – Eric

+0

Я согласен с тем, что часто не стоит рефакторинга на бесплатные очки, особенно трудно добиться безотказной рекурсии, не прибегая к комбинатору с фиксированной запятой. Но я не согласен с тем, что эти вопросы должны быть закрыты как дубликат связанного вопроса, который не касался бесплатных точек, не упоминал библиотеку, не говорил о реорганизации существующего кода и, по сути, только делился с этим что они оба хотели функцию перестановки в JS. Это не делает их дублирующими. –

ответ

0

Там, кажется, несколько проблем с вашим решением, и я боюсь, что у меня нет время преследовать их. (Первое, что я вижу, что вы используете addIndex неправильно.)

Но если вы хотите увидеть рабочую permutation функцию в Ramda, I wrote this некоторое время назад:

// 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

@Eric Каждая функция может быть преобразована в бесконтактную версию. Однако это не означает, что каждая функция должна. Бесполезные функции имеют смысл в очень ограниченных случаях, таких как [эта конверсия] (https://en.wikipedia.org/wiki/Lambda_calculus#.CE.B7-conversion) или [функция композиции] (https: //en.wikipedia .org/вики/Function_composition). В большинстве других случаев точечные функции более читабельны. Существует [алгоритм] (https://en.wikipedia.org/wiki/Combinatory_logic#Completeness_of_the_S-K_basis), чтобы преобразовать точечные выражения в выражения без точек. –

 Смежные вопросы

  • Нет связанных вопросов^_^