I have not programmed in ATS for a while , so I was trying to review ATS
and tried to implement Maybe monad from this discussion thread :
https://groups.google.com/forum/#!searchin/ats-lang-users/monad/ats-lang-users/gGOqTJwiegE/K8ieRTSodDEJ
#include “share/atspre_define.hats”
#include “share/atspre_staload.hats”
datatype Maybe (a : t@ype) =
| Nothing (a) of ()
| Just (a) of (a)
datatype Expr =
| Val of Int
| Div of (Expr , Expr)
(* from UPENN haskell example )
( ok = Div (Div (Val 1972) (Val 2)) (Val 23) *)
val ok = Div (Div ( Val (1972) , Val (2) ) , Val (23))
(* val err = Div (Val 2) (Div (Val 1) (Div (Val 2) (Val 3))) *)
val err = Div (Val (2) , Div (Val (1) , Div (Val (2) , Val (3))))
abst@ype M (t@ype) = ptr
extern
fun {a : t@ype}
ret (v : a ) : M(a)
extern
fun{a,b : t@ype}
bind : M(a) -> M(b)
extern
fun{a,b:t@ype}
bind$cont (x : a) : M(b)
assume M (a : t@ype) = Maybe (a)
extern
fun div (m : int , n : int) : Maybe(int)
implement{a}
ret (x) = Just (x)
implement{a,b}
bind (ma) =
case ma of
| Nothing _ => Nothing ()
| Just (x) => bind$cont<a,b> (x)
fun eval (e : Expr) : Maybe(int) =
case e of
| Val n => ret (n)
| Div (e1 , e2) =>
bind<int,int>(eval (e1)) where {
implement bind$cont<int,int> (m) =
bind<int,int>(eval (e2)) where {
implement bind$cont<int,int> (n) = div (m,n) }}
implement
div (m , n) =
if n = 0
then Nothing ()
else ret (m / n)
fun print_maybe (m : Maybe (int)) : void =
case m of
| Nothing _ => println! (“Nothing”)
| Just (x) => println! (x)
implement main0 () = () where {
val res1 = eval (ok)
val res2 = eval (err)
val _ = print_maybe (res1)
val _ = print_maybe (res2)
}
When run this segfaults , and I think it is because it does not see second
implementation of bind$cont and keep calling the first one which leads to
stack overflow .
Does not second implementation override the first one ?