|
|
last edited 10 years ago by Bill Page |
1 2 3 | ||
Editor: Bill Page
Time: 2014/04/24 01:55:24 GMT+0 |
||
Note: avoid conversion to Float |
changed: -U==>Union(Integer,Float) U:=Union(Integer,Float) changed: -h==>plus(double,double) h:=plus(double,double)
Generic Functions in FriCAS
This acutally works better than I expected.
(1) -> U:=Union(Integer,Float)
(1) |
plus(f:U->U,g:U->U):U->U == (x:U):U +-> if x case Integer then (f(x)::Integer+g(x)::Integer)::U else (f(x)::Float+g(x)::Float)::U
Function declaration plus : ((Union(Integer,Float) -> Union(Integer, Float)), (Union(Integer, Float) -> Union(Integer, Float))) -> ( Union(Integer, Float) -> Union(Integer, Float)) has been added to workspace.
double(n) == n + n
h:=plus(double,double)
Compiling function double with type Union(Integer,Float) -> Union( Integer, Float)
Compiling function plus with type ((Union(Integer,Float) -> Union( Integer, Float)), (Union(Integer, Float) -> Union(Integer, Float))) -> (Union(Integer, Float) -> Union(Integer, Float))
(2) |
h(4)
(3) |
h(3.5)
(4) |
Ref.
---------- Forwarded message ----------:
From: jiazhaoconga <jiazhaoconga@gmail.com> Date: 23 April 2014 09:16 Subject: [fricas-devel] High order (generic) functions To: fricas-devel <fricas-devel@googlegroups.com> I have some problems when I try to have high order generic functions in Fricas: For example, 'plus' is a high order generic functions that takes two functions (f,g) and returns an (anonymous) function (with parameter x) that returns the sum of f(x) and g(x) : 1. Do it in REPL: plus (f,g) == x+->f(x)+g(x) Test it: double n == n + n h := plus(double,double) h 4 but get: FriCAS will attempt to step through and interpret the code. Anonymous user functions created with +-> that are processed in interpret-code mode must have result target information available. This information is not present so FriCAS cannot proceed any further. This may be remedied by declaring the function. 2. Do it in Spad: -- file plus.spad starts here )abbrev package PLSPKG PlusPackage PlusPackage(A:SetCategory, B:AbelianSemiGroup) : Exports == Impl where Exports == with plus2 : ((A->B),(A->B))->(A->B) Impl == add plus2(f,g) == x+->f(x)+g(x) )abbrev package TEST1 TestPlusPackage TestPlusPackage(A:AbelianSemiGroup) : Exports == Impl where Exports == with double2 : A->A Impl == add double2 x == x+x -- file plus.spad ends here and in REPL: )compile plus h == plus2(double2,double2) h 4 but get: There are 1 exposed and 0 unexposed library operations named plus2 having 2 argument(s) but none was determined to be applicable. What/Where is going wrong?
---------- Forwarded message ----------:
From: Waldek Hebisch <hebisch@math.uni.wroc.pl> Date: 23 April 2014 13:51 Subject: Re: [fricas-devel] High order (generic) functions To: fricas-devel@googlegroups.com > > > Hmmm... Acutally I really wouldn't expect this to work in the > > interpreter given what I know about it's design, but it seems OK in > > when using the compiler: > > > > (3) -> h := plus2(double2,double2)$PLSPKG(FLOAT,FLOAT) > > > > (3) theMap(PLSPKG;plus2;3M;1!0,655) > > Type: (Float -> Float) > > (4) -> h 3.5 > > > > (4) 14.0 > > Type: Float > > (5) -> > jiazhaoconga wrote: > Yeah, but I don't want to specify the '$PLSPKG(FLOAT,FLOAT)' by hand, I want > Fricas to do type inference for me, to be exact, I want 'h := > plus2(double2,double2)' > to act like as if the following Spad code have been added into the system: > > AnonymousPackage(A:AbelianSemiGroup) : Exports == Impl where > Exports == with > h : A->A > Impl == add > h x == double2 x+ double2 x > > So that I can do 'h := plus2(double2,double2);h 4; h 3.5' without > specify any type. h := plus2(double2,double2);h 4; h 3.5 in current FriCAS has typing problem: assignment produces value of definite type. So the only way to satify this is to have some type which can be both applied to integer argumements and to float arguments. This is doable, but different from what you think. Basically you need some "universal" type U. Then you need to define elt : (U, U) -> U elt : (U, U, U) -> U and so on up to some maximal arity. Additinally you need coercions from concrete types (like integer) to the universal type. The way to do this is to have type schemes with free parameters (equivalently have "forall" types). Interpreter currently supports limited form of type schemes called "modes". But a mode can have only one free parameter and modes can not be used in some contexts, which unfortunately excludes use of modes in higher order functions. This is not fundamental restriction, but requires better typechecker than what we have now. Concerning use of generic functions defined in Spad files: in Spad you need to specify types in terms of parameters. Interpreter sometimes can infer parameters, but in general you need to give them explicitely. -- Waldek Hebisch