September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
static class PartialApplicationDynamic
|
||||
{
|
||||
// Create a matching delegate type to simplify delegate creation.
|
||||
delegate IEnumerable<TResult> fsDelegate<TSource, TResult>(Func<TSource, TResult> f, IEnumerable<TSource> s);
|
||||
|
||||
static IEnumerable<TResult> fs<TSource, TResult>(Func<TSource, TResult> f, IEnumerable<TSource> s) => s.Select(f);
|
||||
|
||||
static dynamic f1(dynamic x) => x * 2;
|
||||
|
||||
static dynamic f2(dynamic x) => x * x;
|
||||
|
||||
static T[] ArrayConcat<T>(T[] arr1, T[] arr2)
|
||||
{
|
||||
var result = new T[arr1.Length + arr2.Length];
|
||||
Array.Copy(arr1, result, arr1.Length);
|
||||
Array.Copy(arr2, 0, result, 1, arr2.Length);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Use a specialized params delegate to simplify calling at the risk of inadvertent params expansion.
|
||||
delegate TResult partialDelegate<TParams, TResult>(params TParams[] args);
|
||||
static partialDelegate<dynamic, TResult> PartialApplyDynamic<TDelegate, TResult>(TDelegate f, params dynamic[] args) where TDelegate : Delegate
|
||||
{
|
||||
return rest => (TResult)f.DynamicInvoke(ArrayConcat(args, rest).Cast<dynamic>().ToArray());
|
||||
}
|
||||
|
||||
static void Main()
|
||||
{
|
||||
// Cast to object to avoid params expansion of the arrays.
|
||||
object args1 = new object[] { 0, 1, 2, 3 };
|
||||
object args2 = new object[] { 2, 4, 6, 8 };
|
||||
|
||||
var fsf1 = PartialApplyDynamic<fsDelegate<dynamic, dynamic>, IEnumerable<dynamic>>(fs, new Func<dynamic, dynamic>(f1));
|
||||
var fsf2 = PartialApplyDynamic<fsDelegate<dynamic, dynamic>, IEnumerable<dynamic>>(fs, new Func<dynamic, dynamic>(f2));
|
||||
|
||||
Console.WriteLine("fsf1, 0-3: " + string.Join(", ", fsf1(args1)));
|
||||
Console.WriteLine("fsf1, evens: " + string.Join(", ", fsf1(args2)));
|
||||
Console.WriteLine("fsf2, 0-3: " + string.Join(", ", fsf2(args1)));
|
||||
Console.WriteLine("fsf2, evens: " + string.Join(", ", fsf2(args2)));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,18 @@
|
|||
import system'collections.
|
||||
import system'routines.
|
||||
import extensions.
|
||||
import system'collections;
|
||||
import system'routines;
|
||||
import extensions;
|
||||
|
||||
program =
|
||||
[
|
||||
var partial := (:afs:af)((:s)(afs eval(af, s))).
|
||||
public program()
|
||||
{
|
||||
var partial := (afs,af => (s => afs(af, s)));
|
||||
|
||||
var fs := (:f:s)(s selectBy(:x)(f(x)); summarize(ArrayList new); toArray).
|
||||
var f1 := (:x)(x * 2).
|
||||
var f2 := (:x)(x * x).
|
||||
var fs := (f,s => s.selectBy:(x => f(x)).summarize(new ArrayList()).toArray());
|
||||
var f1 := (x => x * 2);
|
||||
var f2 := (x => x * x);
|
||||
|
||||
var fsf1 := partial(fs, f1).
|
||||
var fsf2 := partial(fs, f2).
|
||||
var fsf1 := partial(fs, f1);
|
||||
var fsf2 := partial(fs, f2);
|
||||
|
||||
console printLine(fsf1((2,4,6,8))).
|
||||
console printLine(fsf2((2,4,6,8))).
|
||||
].
|
||||
console.printLine(fsf1(new int[]{2,4,6,8}).toString());
|
||||
console.printLine(fsf2(new int[]{2,4,6,8}).toString())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
Module PartialApplication
|
||||
Function fs(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
|
||||
' This is exactly what Enumerable.Select does.
|
||||
Return s.Select(f)
|
||||
End Function
|
||||
|
||||
Function f1(x As Integer) As Integer
|
||||
Return x * 2
|
||||
End Function
|
||||
|
||||
Function f2(x As Integer) As Integer
|
||||
Return x * x
|
||||
End Function
|
||||
|
||||
' The overload that takes a binary function and partially applies to its first parameter.
|
||||
Function PartialApply(Of T1, T2, TResult)(f As Func(Of T1, T2, TResult), arg As T1) As Func(Of T2, TResult)
|
||||
Return Function(arg2) f(arg, arg2)
|
||||
End Function
|
||||
|
||||
Sub Main()
|
||||
Dim args1 As Integer() = {0, 1, 2, 3}
|
||||
Dim args2 As Integer() = {2, 4, 6, 8}
|
||||
|
||||
Dim fsf1 = PartialApply(Of Func(Of Integer, Integer), IEnumerable(Of Integer), IEnumerable(Of Integer))(AddressOf fs, AddressOf f1)
|
||||
Dim fsf2 = PartialApply(Of Func(Of Integer, Integer), IEnumerable(Of Integer), IEnumerable(Of Integer))(AddressOf fs, AddressOf f2)
|
||||
|
||||
Console.WriteLine("fsf1, 0-3: " & String.Join(", ", fsf1(args1)))
|
||||
Console.WriteLine("fsf1, evens: " & String.Join(", ", fsf1(args2)))
|
||||
Console.WriteLine("fsf2, 0-3: " & String.Join(", ", fsf2(args1)))
|
||||
Console.WriteLine("fsf2, evens: " & String.Join(", ", fsf2(args2)))
|
||||
End Sub
|
||||
End Module
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Option Strict Off
|
||||
|
||||
Partial Module PartialApplicationDynamic
|
||||
Function f1(x As Object) As Object
|
||||
Return x * 2
|
||||
End Function
|
||||
|
||||
Function f2(x As Object) As Object
|
||||
Return x * x
|
||||
End Function
|
||||
End Module
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
Option Strict On
|
||||
|
||||
Partial Module PartialApplicationDynamic
|
||||
' Create a matching delegate type to simplify delegate creation.
|
||||
Delegate Function fsDelegate(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
|
||||
Function fs(Of TSource, TResult)(f As Func(Of TSource, TResult), s As IEnumerable(Of TSource)) As IEnumerable(Of TResult)
|
||||
' This is exactly what Enumerable.Select does.
|
||||
Return s.Select(f)
|
||||
End Function
|
||||
|
||||
Function ArrayConcat(Of T)(arr1 As T(), arr2 As T()) As T()
|
||||
Dim result(arr1.Length + arr2.Length - 1) As T
|
||||
Array.Copy(arr1, result, arr1.Length)
|
||||
Array.Copy(arr2, 0, result, 1, arr2.Length)
|
||||
Return result
|
||||
End Function
|
||||
|
||||
' C# can define ParamArray delegates and VB can consume them, but VB cannot define them on its own.
|
||||
' The argument list of calls to the resulting function thus must be wrapped in a coerced array literal.
|
||||
' VB also doesn't allow Delegate as a type constraint. :(
|
||||
' The function is generic solely to ease use for callers. In this case generics aren't providing any type-safety.
|
||||
Function PartialApplyDynamic(Of TDelegate, TResult)(f As TDelegate, ParamArray args As Object()) As Func(Of Object(), TResult)
|
||||
Dim del = CType(CObj(f), [Delegate])
|
||||
Return Function(rest) CType(del.DynamicInvoke(ArrayConcat(args, rest).Cast(Of Object).ToArray()), TResult)
|
||||
End Function
|
||||
|
||||
Sub Main()
|
||||
Dim args1 As Object = New Object() {0, 1, 2, 3}
|
||||
Dim args2 As Object = New Object() {2, 4, 6, 8}
|
||||
|
||||
Dim fsf1 = PartialApplyDynamic(Of fsDelegate(Of Object, Object), IEnumerable(Of Object))(AddressOf fs, New Func(Of Object, Object)(AddressOf f1))
|
||||
Dim fsf2 = PartialApplyDynamic(Of fsDelegate(Of Object, Object), IEnumerable(Of Object))(AddressOf fs, New Func(Of Object, Object)(AddressOf f2))
|
||||
|
||||
' The braces are array literals.
|
||||
Console.WriteLine("fsf1, 0-3: " & String.Join(", ", fsf1({args1})))
|
||||
Console.WriteLine("fsf1, evens: " & String.Join(", ", fsf1({args2})))
|
||||
Console.WriteLine("fsf2, 0-3: " & String.Join(", ", fsf2({args1})))
|
||||
Console.WriteLine("fsf2, evens: " & String.Join(", ", fsf2({args2})))
|
||||
End Sub
|
||||
End Module
|
||||
Loading…
Add table
Add a link
Reference in a new issue