summaryrefslogtreecommitdiff
path: root/assignment-1/program2.icl
blob: 1c703660303d144fe9b27de81c07e63397743e0f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
module program2

/**
 * Kinds:
 *
 * Bool     *
 * Bin      *->*
 * Rose     *->*
 * Bin Int  *
 * Tree     *->*->*
 * T1       (*->*)->*->*
 * T2       (*->*)->(*->*)->*->*
 * T3       (a->b->*)->a->b->*
 *  - For instance, C3 (1,2) with a = b = *
 *  - Or, C3 (Box [1,2,3]) with a = *->*, b = * (:: Box t u = Box (t u))
 * T4       (b->*)->(a->b)->a->*
 *  - For instance, C4 [[1]] with a = *, b = *
 *  - Or, C4 (IntBox (Box [5])) with a = *->*, b = *->* (:: IntBox t = IntBox (t Int))
 */

import StdEnum
import StdFunc
import StdList
import StdString

class Container t
where
	Cinsert :: a (t a) -> t a | < a
	Ccontains :: a (t a) -> Bool | <, Eq a
	Cshow :: (t a) -> [String] | toString a
	Cnew :: t a

:: Bin a = Leaf | Bin (Bin a) a (Bin a)

instance Container []
where
	Cinsert x xs = [x:xs]
	Ccontains x xs = isMember x xs
		// It would be nice if it were possible to write functions with arity
		// that does not match the type, especially for classes where it is not
		// easy to change the type. This can be implemented as sugar.
	Cshow xs = map toString xs
	Cnew = []

instance Container Bin
where
	Cinsert x Leaf = Bin Leaf x Leaf
	Cinsert x b=:(Bin l y r)
	| x < y     = Bin (Cinsert x l) y r
	| x > y     = Bin l y (Cinsert x r)
	| otherwise = b // Assuming that we don't want to store a value multiple times
	Ccontains _ Leaf = False
	Ccontains x (Bin l y r)
	| x == y    = True
	| x <  y    = Ccontains x l
	| otherwise = Ccontains x r
	Cshow Leaf = []
	Cshow (Bin l x r) = Cshow l ++ [toString x:Cshow r] // Terrible complexity, but easiest implementation
	Cnew = Leaf

Start = (Ccontains 3 c, Cshow c)
where
	c :: Bin Int // Change to [Int] for testing the [] instance
	c = foldr Cinsert Cnew [10..20]