2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,7 +1,15 @@
|
|||
Create a function, <span style="font-family:serif">compose</span>, whose two arguments <span style="font-family:serif">''f''</span> and <span style="font-family:serif">''g''</span>, are both functions with one argument.
|
||||
The result of <span style="font-family:serif">compose</span> is to be a function of one argument, (lets call the argument <span style="font-family:serif">''x''</span>), which works like applying function <span style="font-family:serif">''f''</span> to the result of applying function <span style="font-family:serif">''g''</span> to <span style="font-family:serif">''x''</span>, i.e,
|
||||
: <span style="font-family:serif">compose(''f'', ''g'') (''x'') = ''f''(''g''(''x''))</span>
|
||||
;Task:
|
||||
Create a function, <span style="font-family:serif">compose</span>, whose two arguments <span style="font-family:serif">''f''</span> and <span style="font-family:serif">''g''</span>, are both functions with one argument.
|
||||
|
||||
|
||||
The result of <span style="font-family:serif">compose</span> is to be a function of one argument, (lets call the argument <span style="font-family:serif">''x''</span>), which works like applying function <span style="font-family:serif"> ''f'' </span> to the result of applying function <span style="font-family:serif"> ''g'' </span> to <span style="font-family:serif"> ''x''</span>.
|
||||
|
||||
|
||||
;Example:
|
||||
<span style="font-family:serif">compose(''f'', ''g'') (''x'') = ''f''(''g''(''x''))</span>
|
||||
|
||||
|
||||
Reference: [[wp:Function composition (computer science)|Function composition]]
|
||||
|
||||
Hint: In some languages, implementing <span style="font-family:serif">compose</span> correctly requires creating a [[wp:Closure (computer science)|closure]].
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
-- Compose two functions where each function is
|
||||
-- a script object with a call(x) handler.
|
||||
on compose(f, g)
|
||||
script
|
||||
on call(x)
|
||||
f's call(g's call(x))
|
||||
end call
|
||||
end script
|
||||
script
|
||||
on call(x)
|
||||
f's call(g's call(x))
|
||||
end call
|
||||
end script
|
||||
end compose
|
||||
|
||||
script sqrt
|
||||
on call(x)
|
||||
x ^ 0.5
|
||||
end call
|
||||
on call(x)
|
||||
x ^ 0.5
|
||||
end call
|
||||
end script
|
||||
|
||||
script twice
|
||||
on call(x)
|
||||
2 * x
|
||||
end call
|
||||
on call(x)
|
||||
2 * x
|
||||
end call
|
||||
end script
|
||||
|
||||
compose(sqrt, twice)'s call(32)
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
-- Compose (right to left) a list of ordinary 2nd class handlers (of arbitrary length)
|
||||
|
||||
-- compose :: [(a -> a)] -> (a -> a)
|
||||
on compose(fs)
|
||||
script
|
||||
on lambda(x)
|
||||
script
|
||||
on lambda(a, f)
|
||||
mReturn(f)'s lambda(a)
|
||||
end lambda
|
||||
end script
|
||||
|
||||
foldr(result, x, fs)
|
||||
end lambda
|
||||
end script
|
||||
end compose
|
||||
|
||||
|
||||
-- TEST
|
||||
|
||||
on root(x)
|
||||
x ^ 0.5
|
||||
end root
|
||||
|
||||
on succ(x)
|
||||
x + 1
|
||||
end succ
|
||||
|
||||
on half(x)
|
||||
x / 2
|
||||
end half
|
||||
|
||||
|
||||
on run
|
||||
|
||||
tell compose([half, succ, root]) to lambda(5)
|
||||
|
||||
--> 1.61803398875
|
||||
end run
|
||||
|
||||
|
||||
|
||||
-- GENERIC FUNCTIONS
|
||||
|
||||
-- foldr :: (a -> b -> a) -> a -> [b] -> a
|
||||
on foldr(f, startValue, xs)
|
||||
tell mReturn(f)
|
||||
set v to startValue
|
||||
set lng to length of xs
|
||||
repeat with i from lng to 1 by -1
|
||||
set v to lambda(v, item i of xs, i, xs)
|
||||
end repeat
|
||||
return v
|
||||
end tell
|
||||
end foldr
|
||||
|
||||
-- Lift 2nd class handler function into 1st class script wrapper
|
||||
-- mReturn :: Handler -> Script
|
||||
on mReturn(f)
|
||||
if class of f is script then
|
||||
f
|
||||
else
|
||||
script
|
||||
property lambda : f
|
||||
end script
|
||||
end if
|
||||
end mReturn
|
||||
79
Task/Function-composition/Fortran/function-composition.f
Normal file
79
Task/Function-composition/Fortran/function-composition.f
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
module functions_module
|
||||
implicit none
|
||||
private ! all by default
|
||||
public :: f,g
|
||||
|
||||
contains
|
||||
|
||||
pure function f(x)
|
||||
implicit none
|
||||
real, intent(in) :: x
|
||||
real :: f
|
||||
f = sin(x)
|
||||
end function f
|
||||
|
||||
pure function g(x)
|
||||
implicit none
|
||||
real, intent(in) :: x
|
||||
real :: g
|
||||
g = cos(x)
|
||||
end function g
|
||||
|
||||
end module functions_module
|
||||
|
||||
module compose_module
|
||||
implicit none
|
||||
private ! all by default
|
||||
public :: compose
|
||||
|
||||
interface
|
||||
pure function f(x)
|
||||
implicit none
|
||||
real, intent(in) :: x
|
||||
real :: f
|
||||
end function f
|
||||
|
||||
pure function g(x)
|
||||
implicit none
|
||||
real, intent(in) :: x
|
||||
real :: g
|
||||
end function g
|
||||
end interface
|
||||
|
||||
contains
|
||||
|
||||
impure function compose(x, fi, gi)
|
||||
implicit none
|
||||
real, intent(in) :: x
|
||||
procedure(f), optional :: fi
|
||||
procedure(g), optional :: gi
|
||||
real :: compose
|
||||
|
||||
procedure (f), pointer, save :: fpi => null()
|
||||
procedure (g), pointer, save :: gpi => null()
|
||||
|
||||
if(present(fi) .and. present(gi))then
|
||||
fpi => fi
|
||||
gpi => gi
|
||||
compose = 0
|
||||
return
|
||||
endif
|
||||
|
||||
if(.not. associated(fpi)) error stop "fpi"
|
||||
if(.not. associated(gpi)) error stop "gpi"
|
||||
|
||||
compose = fpi(gpi(x))
|
||||
|
||||
contains
|
||||
|
||||
end function compose
|
||||
|
||||
end module compose_module
|
||||
|
||||
program test_compose
|
||||
use functions_module
|
||||
use compose_module
|
||||
implicit none
|
||||
write(*,*) "prepare compose:", compose(0.0, f,g)
|
||||
write(*,*) "run compose:", compose(0.5)
|
||||
end program test_compose
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
|
||||
// iterativeComposed :: [f] -> f
|
||||
function iterativeComposed(fs) {
|
||||
|
||||
return function (x) {
|
||||
var i = fs.length,
|
||||
e = x;
|
||||
|
||||
while (i--) e = fs[i](e);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
// foldComposed :: [f] -> f
|
||||
function foldComposed(fs) {
|
||||
|
||||
return function (x) {
|
||||
return fs
|
||||
.reduceRight(function (a, f) {
|
||||
return f(a);
|
||||
}, x);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
var sqrt = Math.sqrt,
|
||||
|
||||
succ = function (x) {
|
||||
return x + 1;
|
||||
},
|
||||
|
||||
half = function (x) {
|
||||
return x / 2;
|
||||
};
|
||||
|
||||
|
||||
// Testing two different multiple composition ([f] -> f) functions
|
||||
|
||||
return [iterativeComposed, foldComposed]
|
||||
.map(function (compose) {
|
||||
|
||||
// both functions compose from right to left
|
||||
return compose([half, succ, sqrt])(5);
|
||||
|
||||
});
|
||||
})();
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
|
||||
// compose :: [(a -> a)] -> (a -> a)
|
||||
let compose = fs => x => fs.reduceRight((a, f) => f(a), x);
|
||||
|
||||
|
||||
// TEST a composition of 3 functions (right to left)
|
||||
|
||||
let sqrt = Math.sqrt,
|
||||
|
||||
succ = x => x + 1,
|
||||
|
||||
half = x => x / 2;
|
||||
|
||||
|
||||
return compose([half, succ, sqrt])(5);
|
||||
|
||||
// --> 1.618033988749895
|
||||
})();
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
f = { |x| x + 1 };
|
||||
g = { |x| x * 2 };
|
||||
h = g <> f;
|
||||
h.(8); // returns 18
|
||||
Loading…
Add table
Add a link
Reference in a new issue