K Combinator (C #, Scala)
ฉันใช้ K combinator ใน Ruby บ่อยครั้งส่วนใหญ่จะเป็นเท่าเมื่อการพับถูกดำเนินการผ่านผลข้างเคียงมากกว่าค่าตอบแทนเช่นในตัวอย่างนี้:
some_collection.reduce(Hash.new(0)) {|acc, el| acc[el] += 1 }
some_collection
ข้อหานี้ความถี่ที่แต่ละองค์ประกอบที่เกิดขึ้นใน น่าเสียดายที่มันใช้งานไม่ได้เนื่องจากบล็อกต้องส่งคืนค่าใหม่ของตัวสะสมในแต่ละการวนซ้ำ แต่ในการกำหนดค่า Ruby จะประเมินค่าที่ได้รับมอบหมาย
ดังนั้นคุณต้องส่งคืนค่าใหม่ของแอคคูมูเลเตอร์ดังนี้:
some_collection.reduce(Hash.new(0)) {|acc, el| acc[el] += 1; acc }
แต่ฉันพบว่าการเรียงลำดับอย่างชัดเจนน่าเกลียดในสไตล์ฟังก์ชั่น - อิชนี้โดยใช้การพับ K combinator (เรียกว่าObject#tap
Ruby) ช่วยเหลือ:
some_collection.reduce(Hash.new(0)) {|acc, el| acc.tap { acc[el] += 1 }}
ฉันพลาดไปแล้วสองสามครั้งใน C # (ส่วนใหญ่เป็นเพราะเหตุผลบางอย่างในการรวบรวมคอลเลกชันเช่นการList.Add
ส่งคืนvoid
แทนthis
) และ Scala ดังนั้นฉันจึงพกพาสิ่งนี้:
namespace GenericExtensions
{
public static class GenericExtensions
{
public static T Tap<T>(this T o, Action<T> f)
{
Contract.Requires(o != null);
Contract.Requires(f != null);
f(o);
return o;
}
public static T Tap<T>(this T o, Action f)
{
Contract.Requires(o != null);
Contract.Requires(f != null);
f();
return o;
}
}
}
และในสกาลา:
class Tap[T](o: T) {
def tap(f: T => Unit) = { f(o); o }
def tap(f: => Unit) = { f; o }
}
object Implicits { implicit def any2Tap[T](o: T) = new Tap(o) }
ฟังก์ชั่นเอกลักษณ์ (ทับทิม)
บางสิ่งที่ฉันขาดไปใน Ruby เป็นวิธีการเข้าถึงฟังก์ชั่นระบุตัวตน Haskell มีฟังก์ชั่นตัวตนภายใต้ชื่อid
, Scala identity
ภายใต้ชื่อ สิ่งนี้อนุญาตให้หนึ่งเขียนโค้ดเช่น:
someCollection.groupBy(identity)
เทียบเท่าในทับทิมคือ
some_collection.group_by {|x| x }
ลิ้นไม่ได้ไหลออกมาใช่มั้ย
การแก้ไขคือ
IDENTITY = -> x { x }
some_collection.group_by(&IDENTITY)
ForEach (.NET)
อีกวิธีที่ขาดหายไปอย่างมากใน C #:
namespace IEnumerableExtensions
{
public static class IEnumerableExtensions
{
public static void ForEach<T>(this IEnumerable<T> xs, Action<T> f)
{
Contract.Requires(xs != null);
Contract.Requires(f != null);
foreach (var x in xs) f(x);
}
}
}