10. Typeclasses
Felix has typeclasses similar to Haskell.
Start felix section to tut/tutorial/tut-9-0.flx[1
/1
]
1: #line 6035 "./lpsrc/flx_tutorial.pak"
2:
3:
4:
5: typeclass XStr[T] {
6: virtual fun str2: T->string;
7: }
8:
9: instance XStr[int] {
10: fun str2 (x:int):string => str x;
11: }
12:
13: open List;
14:
15: fun foo[T with XStr[T]] (x:list[T]):string =>
16: match x with
17: | Empty[T] => "()"
18: | Cons(?h, ?t) => "(" + (str2 h) + ", " + (foo t) + ")"
19: endmatch
20: ;
21:
22: val x = list(1,2);
23: print$ foo x; endl;
Start data section to tut/tutorial/tut-9-0.expect[1
/1
]
in a module:
Start felix section to tut/tutorial/tut-9-1.flx[1
/1
]
1: #line 6064 "./lpsrc/flx_tutorial.pak"
2:
3:
4:
5: open List;
6:
7: typeclass XStr[T] {
8: virtual fun str2: T->string;
9: }
10:
11: module Foo {
12: instance XStr[int] {
13: fun str2 (x:int):string => str x;
14: }
15:
16: fun foo[T with XStr[T]] (x:T):string => str2 x;
17:
18: fun foo[T with XStr[T]] (x:list[T]):string =>
19: match x with
20: | Empty[T] => "()"
21: | Cons(?h, ?t) => "(" + (str2 h) + ", " + (foo t) + ")"
22: endmatch
23: ;
24: }
25:
26: open Foo;
27:
28: print$ Foo::foo 5; endl;
29: print$ Foo::foo$ list(1,2,3,4); endl;
30:
Start data section to tut/tutorial/tut-9-1.expect[1
/1
]
1: 5
2: (1, (2, (3, (4, ()))))
Start felix section to tut/tutorial/tut-9-2.flx[1
/1
]
1: #line 6099 "./lpsrc/flx_tutorial.pak"
2:
3:
4:
5: typedef fun Maybe (t:TYPE):TYPE=>opt[t];
6:
7: instance Monad [the Maybe] {
8: fun bind[a,b] (x:Maybe a, f:a -> Maybe b) =>
9: match x with
10: | None[a] => None[b]
11: | Some ?x => f x
12: endmatch
13: ;
14:
15: fun ret[a](x:a):Maybe a => Some x;
16: }
17:
18: fun madd(x:double) (y:double):opt[double]=>Some (y+x);
19: fun msub(x:double) (y:double):opt[double]=>Some (y-x);
20: fun mmul(x:double) (y:double):opt[double]=>Some (y*x);
21: fun mdiv(x:double) (y:double):opt[double]=>
22: if x == 0.0 then None[double] else Some (y/x) endif
23: ;
24: fun mneg(x:double):opt[double]=>Some (-x);
25:
26: open Monad[the Maybe];
27:
28: proc show(r:Maybe double) {
29: match r with
30: | Some ?x => { print x; }
31: | None => { print "divide by zero somewhere"; }
32: endmatch; endl;
33: }
34:
35:
36:
37:
38: var x1 = 2.7; var y1 = 1.2; var z = 0.0;
39: {
40: var r = ret x1 >>= msub y1 >>= mdiv z;
41: show r;
42: };
43:
44: {
45: var r = ret x1 >>= msub y1 >>= mdiv 2.0;
46: show r;
47: };
Start data section to tut/tutorial/tut-9-2.expect[1
/1
]
1: divide by zero somewhere
2: 0.75