K Birleştirici (C #, Scala)
K birleştiricisini Ruby'de oldukça sık, çoğunlukla katlama işleminin bu örnekte olduğu gibi bir geri dönüş değeri yerine bir yan efektle gerçekleştirildiğinde katlamalarda kullanıyorum:
some_collection.reduce(Hash.new(0)) {|acc, el| acc[el] += 1 }
Bu, her bir elemanın ne sıklıkta gerçekleştiğini sayar some_collection
. Ne yazık ki, aslında işe yaramaz, çünkü blok her tekrarlamada akünün yeni değerini döndürmek zorundadır, ancak Ruby atamalarında atanan değere göre değerlendirilir.
Dolayısıyla, akümülatörün yeni değerini açık bir şekilde bu şekilde döndürmeniz gerekir:
some_collection.reduce(Hash.new(0)) {|acc, el| acc[el] += 1; acc }
Ancak bu tür açık dizilimleri, bu işlevsel-ish stilinde, kıvrımları kullanarak çirkin buluyorum. K birleşimi ( Object#tap
Ruby'de denir ) kurtarmaya:
some_collection.reduce(Hash.new(0)) {|acc, el| acc.tap { acc[el] += 1 }}
C # 'da birkaç kez çok fazla özledim (çoğunlukla bazı nedenlerden dolayı List.Add
geri dönüş gibi mutasyonlar void
nedeniyle this
) ve Scala, bu yüzden bunu yapıyorum:
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;
}
}
}
ve Scala'da:
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) }
Kimlik İşlevi (Yakut)
Ruby'de kaçırdığım bir şey, kimlik işlevine erişmek için güzel bir şekilde adlandırılmış bir yoldur. Haskell isminin id
altında Scala ismini, ismin altında Scala ismini verir identity
. Bu, birinin şöyle bir kod yazmasını sağlar:
someCollection.groupBy(identity)
Ruby'deki karşılığı
some_collection.group_by {|x| x }
Dilden tam olarak çıkmıyor, değil mi?
Düzeltme
IDENTITY = -> x { x }
some_collection.group_by(&IDENTITY)
ForEach (.NET)
C # başka bir çok sık eksik yöntem:
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);
}
}
}