To help make this more concrete, I did a quick implementation of a
Partial domain in Spad (attached).

As a toy example comparing Union("failed", ...) with Partial(...):

UFloat ==> Union(Float,"failed")
partialSqrt x == (x>=0.0 => sqrt x; "failed") :: UFloat
partialSqrt 4.0 -- ok
partialSqrt (-4.0) -- ok

partialSqrt2 x == (x>=0.0 => partial sqrt x; failed()$Partial(Float))
partialSqrt2 4.0 -- ok
partialSqrt2 (-4.0) -- ok

The Partial domain avoids the explicit union type, but the "failed"
keyword from the union is shorter.

For this example (*without generalising*), the H-M type inference from
SML/Ocaml/Haskell is more elegant:

SML: fun partialSqrt x = if x>=0.0 then SOME (Math.sqrt x) else NONE;

Kindly, Mark.

On 24/02/2021 14:52, Qian Yun wrote:


On 2/24/21 9:48 PM, Ralf Hemmecke wrote:
I'm almost sure that "Maybe" doesn't need special Haskell
compiler treatment, a user implemented "Maybe" can achieve
similar performance.  Because "Maybe" is such a simple
structure, the compiler can optimize it right away, no
need to special treat it at all.

Apart from such optimizations... why do you want Maybe instead of
Partial?

I'm not promoting "Maybe" over "Partial".

As you said bellow, I'm not discussing about naming right now,
but to let everyone agree to move away from "failed"
to "this functional style error handling".

Thanks for your interest in my proposal.

- Qian

(in axllib)
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpippijn%2Faldor%2Fblob%2Fmaster%2Faldor%2Flib%2Faxllib%2Fsrc%2Fal%2Fpartial.as&data=04%7C01%7Cmark.clements%40ki.se%7C7feb4780472b4e54e1d408d8d8cb79cb%7Cbff7eef1cf4b4f32be3da1dda043c05d%7C0%7C0%7C637497715729347066%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=Aih8fRhdM8k%2FJvUIGvVA9UX1qNIW%2FzOC7FN0%2BRDn%2BjM%3D&reserved=0


(or a bit more extended in the libaldor)
https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fpippijn%2Faldor%2Fblob%2Fmaster%2Faldor%2Flib%2Faldor%2Fsrc%2Fbase%2Fsal_partial.as&data=04%7C01%7Cmark.clements%40ki.se%7C7feb4780472b4e54e1d408d8d8cb79cb%7Cbff7eef1cf4b4f32be3da1dda043c05d%7C0%7C0%7C637497715729347066%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=nWRpGnvFomePzwwwPJh4OMsNgoH7iMMpXh9KsyvqQKk%3D&reserved=0


Wouldn't that just be a question of naming?

I somehow would like failed?(x) better than isNothing(x) or isJust(x).

Anyway, I also like Partial/Maybe better than Union(X,"failed").
The Union(X,"failed") stuff is quite common in the FriCAS algebra
library. It doesn't mean that one must replace Union(X, "error1",
"error2") where two error cases are considered. But introducing
Partial/Mabe could produce more readable code and would certainly make
translating SPAD code to Aldor easier.

Ralf




När du skickar e-post till Karolinska Institutet (KI) innebär detta att KI kommer att 
behandla dina personuppgifter. Här finns information om hur KI behandlar 
personuppgifter<https://ki.se/medarbetare/integritetsskyddspolicy>.


Sending email to Karolinska Institutet (KI) will result in KI processing your 
personal data. You can read more about KI’s processing of personal data 
here<https://ki.se/en/staff/data-protection-policy>.

--
You received this message because you are subscribed to the Google Groups "FriCAS - 
computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/fricas-devel/49beb7e8-79c9-340a-b5d7-041a62c8157d%40ki.se.
)abbrev domain PARTIAL Partial

Partial(T:Type): Exports == Implementation where
  Exports ==> with 
     -- Aldor's signature (subset)
     construct: T -> %
     failed: () -> % -- cf failed:%
     failed?: % -> Boolean
     retract: % -> T
     valueOr: (%, T) -> T
     if T has CoercibleTo(OutputForm) then
        coerce : % -> OutputForm
     -- Suggested additions
     coerce: T -> %
     coerce: % -> T
     failed: T -> %
     partial: T -> %
     partialIf: (Boolean,T) -> %
  Implementation ==> add 

     Rep ==> Union(T, "failed") -- cf Record(val:T)
     rep (x : %) ==> x pretend Rep
     per (x : Rep) ==> x pretend %

     -- Aldor
     failed()             == per ("failed" :: Rep) -- cf failed:% == per nil
     failed?(x:%):Boolean == (rep x) case "failed"
     construct(x:T):%          == per (x :: Rep)
     retract(x:%):T       == rep(x) :: T -- without assert(~failed? x)
     valueOr(x: %, def: T): T == if failed? x then def else retract x
     if T has CoercibleTo(OutputForm) then
       coerce(x:%):OutputForm == (rep x) :: OutputForm

     -- suggested additions
     coerce(x:T):%       == per (x :: Rep)
     coerce(x:%):T       == rep(x) :: T -- assert(~failed? x)
     failed(x:T):% == failed()
     partial(x:T):% == x :: %
     partialIf(predicate:Boolean,x:T):% == if predicate then x :: % else 
failed()
 
)if false

)cd /home/marcle/work
)compile partial.spad

x : Partial(Float) := 1.0
x :: Float -- ok
failed? x
x := failed() -- ok
failed? x

partial 1 -- ok
failed 1  -- ok (requires valid value)
failed() @ Partial(Integer) -- clumsy
failed()$Partial(Integer)   -- clumsy

UFloat ==> Union(Float,"failed")
partialSqrt x == (x>=0.0 => sqrt x; "failed") :: UFloat
partialSqrt 4.0 -- ok
partialSqrt (-4.0) -- ok

partialSqrt2 x == (x>=0.0 => partial sqrt x; failed()$Partial(Float))
partialSqrt2 4.0 -- ok
partialSqrt2 (-4.0) -- ok

-- SML
-- fun partialSqrt x = if x>=0.0 then SOME (Math.sqrt x) else NONE;
-- partialSqrt 4.0; 
-- partialSqrt ~4.0;
)endif

Reply via email to