2017-10-15 6 views
2

javascriptでアプリケーションファンクタを使用する方法を学習しようとしていて、apメソッドを使用しました。Ramda's apで動作しない私のアプリケーションファンクタは何ですか?

const buildMerch = product => option => color =>`${product}-${option}-${color}` 

const merchandise = R.ap([buildMerch], [products, options, colors]) 

しかし、これは私に三つの機能バック与えている:

をだから私はこれをしようとしています documentationあたりとして

const products = ['teeshirt', 'sweater'] 
const options = ['large', 'medium', 'small'] 
const colors = ['red', 'black'] 

:私はそうのような3つの配列を結合するためにそれを使用しようとしています

[function (option) { 
    return function (color) { 
    return product + '-' + option + '-' + color; 
    }; 
}, function (option) { 
    return function (color) { 
    return product + '-' + option + '-' + color; 
    }; 
}, function (option) { 
    return function (color) { 
    return product + '-' + option + '-' + color; 
    }; 
}] 

...私が期待している配列の組み合わせた結果の代わりに...

["teeshirt- large-red", "teeshirt- large-black", "teeshirt- medium-red", "teeshirt- medium-black", "teeshirt- small-red", "teeshirt- small-black", "sweater- large-red", "sweater- large-black", "sweater- medium-red", "sweater- medium-black", "sweater- small-red", "sweater- small-black"] 

私は間違っていますか?これをどうやって解決するのですか?ここで

が問題とjsbinです:https://jsbin.com/fohuriy/14/edit?js,console

答えて

3

apは、ドキュメントごとに、値のリストに関数のリストを適用します。あなたの機能buildMerchは、以下の "タイプ" があります。

buildMerch :: String -> String -> String -> String 

apの最も単純な種類はmapです:任意の応用的ファンクタのために、我々が得る:アレイの場合

pure f <*> a 
    ====== 
map f a 

を、purex => [x]です。ですから、引数リストの上にマッピングすることでbuildMerch

R.ap([buildMerch], [foo, bar, baz]) 
    ====== 
R.map(buildMerch, [foo, bar, baz]) 

は、我々は、部分的に問題の配列に適用されます。何をしたいん式は次のとおりです。

const merchandise = R.ap(R.ap(R.map(buildMerch, products), options), colors); 

まず、我々は製品のアレイの上buildMerchをマップします。これにより、2つの引数、すなわち[String -> String -> String]を取る関数の配列が得られます。次にR.apを使用してそれをoptions :: [String]に結合します。これは最初の配列の各関数をoptions配列の各引数に適用します。今度は[String -> String]があり、最後にR.apという文字列を返します。colorsで、最終的な文字列を取得します。

+2

良い説明、ありがとうございました! –

1

APは、値のリストに関数のリストを適用します。あなたの場合、buildMerchを指定された配列のすべての要素(productsoptions、その後はcolors)で呼び出し、配列内のすべての組み合わせで呼び出すことはありません。これは3つの引数が必要なメソッドのシグネチャには一致しません。

1

この問題を解決する別の方法は、apをネイティブのjavascript配列に追加することです。この方法では、基本的にArrayをアプリケーションファンクタに変え、ライブラリは必要なく、使用したいアプリケーションファクタと同じインタフェースで動作します。

// add ap 
Array.prototype.ap = function(anotherArray) { 
    return this.map(el => 
    anotherArray.map(el) 
).flatten(); 
}; 

これは、flatten(または 'join')に依存します。今

// add flatten 
Array.prototype.flatten = function() { 
    let results = []; 
    this.forEach(subArray => { 
    subArray.forEach(item => { 
     results.push(item); 
    }); 
    }); 
    return results; 
}; 

const products = ['teeshirt', 'sweater']; 
const options = ['large', 'medium', 'small']; 
const colors = ['red', 'black']; 
const buildMerch = product => option => color =>`${product}-${option}-${color}`; 

const merchandise = products.map(buildMerch).ap(options).ap(colors); 

今、あなたはまた、3つのすべてを持ち上げ可能性:

const liftA3 = (fn, functor1, functor2, functor3) => 
    functor1.map(fn).ap(functor2).ap(functor3); 

liftA3(buildMerch, products, options, colors) // also returns merchandise 
関連する問題