login  home  contents  what's new  discussion  bug reports     help  links  subscribe  changes  refresh  edit

Generic Functions in FriCAS

This acutally works better than I expected.

fricas
U:=Union(Integer,Float)

\label{eq1}\hbox{\axiomType{Union}\ } (\hbox{\axiomType{Integer}\ } , \hbox{\axiomType{Float}\ })(1)
Type: Type
fricas
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.
Type: Void
fricas
double(n) == n + n
Type: Void
fricas
h:=plus(double,double)
fricas
Compiling function double with type Union(Integer,Float) -> Union(
      Integer,Float)
fricas
Compiling function plus with type ((Union(Integer,Float) -> Union(
      Integer,Float)),(Union(Integer,Float) -> Union(Integer,Float)))
       -> (Union(Integer,Float) -> Union(Integer,Float))

\label{eq2}\mbox{theMap (...)}(2)
Type: (Union(Integer,Float) -> Union(Integer,Float))
fricas
h(4)

\label{eq3}16(3)
Type: Union(Integer,...)
fricas
h(3.5)

\label{eq4}14.0(4)
Type: Union(Float,...)

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




  Subject:   Be Bold !!
  ( 13 subscribers )  
Please rate this page: