我的目標是創建一個自定義映射函數,首先需要過濾列表以保留,例如,在調用每個項目上提供的函數之前,只有偶數項目。我確實需要將curried函數和第一個參數作爲函數,而不是列表。我相信簽名看起來是這樣的:(a -> b) -> [a] -> [b]
用於生成更高階函數的習語拉姆達?
當然有很多方法可以做到這一點。這是我第一次嘗試的樣子。
var isEven = x => x % 2 === 0;
var filterEvensMap = R.curry((fn, items) => R.map(fn, R.filter(isEven, items)));
filterEvensMap(R.negate, [1,2,3,4]); // [-2, -4]
然而,由於上述使用匿名函數與fn
和items
「膠水參數」,我不知道這是Ramda旨在使用方式。
下面我介紹了另一種方式來做到這一點。這似乎更多的是拉姆達的精神,但我不確定我是否過於複雜。
var filterEvensMap = R.compose(
R.flip,
R.uncurryN(2)
)(R.compose(
R.flip(R.map),
R.filter(isEven)
));
我是否過度使用多個撰寫和uncurryN?有沒有更實用的方法來實現這一目標?根據你的經驗,這有什麼關係嗎?
在此先感謝。
嗨,謝謝你的提示,pointfree.js看起來真的很有幫助。儘管在OP中的預期行爲與從無點Haskell表達式導出的Ramda表達式之間存在輕微的不匹配:過濾需要發生在原始的vals上,而不是映射的vals上。以下是顯示不同之處的鏈接:http://goo.gl/KVX4Kv。我對Haskell語法並不熟悉,所以我仍然試圖找出問題所在。 – Lopatin
哦,我犯了一個錯誤,它應該是'compose(pipe(filter(f)),map)',但它不會在Ramda出於某種原因。我的猜測是,自動壓縮和可變數組合/管道混亂的事情,但你可以看到它在香草JS在這裏工作:https://jsfiddle.net/xs56h0vb/ – elclanrs
再次感謝!我正在評價答案,因爲我擁有繼續編程所需的一切。我現在意識到,我在這個問題中提到的是一個名爲「pointfree」的概念,並且它並不總是有必要寫出一個無點表達式,只是因爲它是可能的。但是,當我想要獲得樂趣的時候,有一個pointfree.js – Lopatin