[clean-list] Understanding Generics

Arjen van Weelden A.vanWeelden at cs.ru.nl
Tue Aug 1 09:55:10 MEST 2006


Hi Alex,

It is my fault, I didn't make gsub lazy enough.
To fix it, replace
generic gsub a :: !String a -> (!(Rep -> a), Rep, ![Rep])
with
generic gsub a :: !String a -> (!(Rep -> a), Rep, [Rep])

Please remember that this is neither an elegant nor a typical generic 
function. I don't recommend its usage. I've not been able to find an 
elegant solution with a type like a -> [a].

kind regards,
	Arjen

Alexsandro Soares wrote:
> Hi Arjen,
> 
>    Thank you again for your answer. 
> 
>    If I try to define the following type
>    
>    :: MyTree a = B (MyTree a) (MyTree a) | L a | None 
> 
> and then I try the following
> 
>     Start = sub (B (L 1) (L 2))
> 
> the compiler complains with
> 
>   [(B (L 1) (L 2)),Run time error, rule
> '<case>[line:80];32;113' in module 'GenSub' does not
> match.
> 
>    If I change the order in type definition to
> 
>    :: MyTree a =  L a | None | B (MyTree a) (MyTree a)
> 
>    then it works well and give me the following answer
>  
> 
>        [(B (L 1) (L 2)),(L 1),(L 2)]
> 
>    I can't understand this behaviour. Do you have any
> explanation?
> 
>   Regards,
>   Alex
> 
> 
> 
> 
> --- Arjen van Weelden <A.vanWeelden at cs.ru.nl>
> escreveu:
> 
>> Hi Alex,
>>
>> This was not as easy as I expected. The problem is
>> that you have to 
>> gather values of a certain type, but you cannot
>> combine them in PAIRs.
>> If this is your first attempt at a generic function,
>> please use more 
>> simple (c.f. Libraries\Generics) examples to learn
>> from.
>>
>> Have a look at the attached solution. Detecting the
>> values of a certain 
>> type is done in the {|OBJECT|} instance using the
>> name of the type as a 
>> String. Gathering the values is done using the Rep
>> type, which can 
>> contain any type by mimicking its generic structure,
>> and "parsing" them 
>> back to the original type. It has been made lazy
>> enough to get the 
>> "parser" without passing a real value, required in
>> the {|EITHER|} instance.
>>
>> module GenSub
>>
>> import StdList, StdFunc, StdString, StdGeneric
>>
>> :: Tree a = L a | B (Tree a) (Tree a)
>>
>> subTree :: (Tree a) -> [Tree a]
>> subTree t=:(B l r) = [t:subTree l] ++ subTree r
>> subTree (L a) = [L a]
>>
>> subList :: [a] -> [[a]]
>> subList l=:[_:xs] = [l:subList xs]
>> subList _ = [[]]
>>
>> sub :: !a -> [a] | gsub{|*|} a
>> sub x = map p [y:ys]
>> where
>> 	(p, y, ys) = gsub{|*|} "" x
>>
>> Start = (subList [1, 2, 3], subTree (B (L 1) (L 2)),
>> "\n", sub [1, 2, 3], sub (B (L 1) (L 2)))
>>
>> derive bimap [], (,,)
>> derive gsub [], Tree
>>
>> :: Rep = Pair !Rep !Rep | Left !Rep | Right !Rep |
>> Unit | Int !Int
>>
>> generic gsub a :: !String a -> (!(Rep -> a), Rep,
>> ![Rep])
>>
>> gsub{|Int|} _ i = (\(Int i) -> i, Int i, [])
>>
>> gsub{|UNIT|} _ _ = (\Unit -> UNIT, Unit, [])
>>
>> gsub{|CONS of gcd|} sub_a name cons = (CONS o px, x,
>> xs) 
>> where
>> 	(px, x, xs) = sub_a name (case cons of CONS a -> a)
>>
>> gsub{|OBJECT of gtd|} sub_a name object = (OBJECT o
>> px, x, if (gtd.gtd_name == name) [x:xs] xs)
>> where
>> 	(px, x, xs) = sub_a (if (name == "") gtd.gtd_name
>> name) (case object of OBJECT a -> a)
>> 	
>> gsub{|EITHER|} sub_a sub_b name e = (p, r, rs)
>> where
>> 	(r, rs) = case e of
>> 		LEFT a 
>> 			# (_, x, xs) = sub_a name a
>> 			-> (Left x, xs)
>> 		RIGHT b 
>> 			# (_, y, ys) = sub_b name b
>> 			-> (Right y, ys)
>> 	p (Left r) 
>> 		# (px, _, _) = sub_a name (case e of LEFT a -> a)
>> 		= LEFT (px r)
>> 	p (Right r) 
>> 		# (py, _, _) = sub_b name (case e of RIGHT b -> b)
>> 		= RIGHT (py r)
>>
>> gsub{|PAIR|} sub_a sub_b name pair = (\(Pair r1 r2)
>> -> PAIR (px r1) (py r2), Pair x y, xs ++ ys)
>> where
>> 	(px, x, xs) = sub_a name (case pair of PAIR a _ ->
>> a)
>> 	(py, y, ys) = sub_b name (case pair of PAIR _ b ->
>> b)
>>
> 
> 
> 
> 		
> _______________________________________________________ 
> Novidade no Yahoo! Mail: receba alertas de novas mensagens no seu celular. Registre seu aparelho agora! 
> http://br.mobile.yahoo.com/mailalertas/ 
>  
> 


More information about the clean-list mailing list