
Chaddaï and Richard,
Both your reply's helped me alot! It is so much different then imperative
programming, and i say it as a good thing. I still have lots to learn, but
its just like math, it looks so obvious when you see the solution, but
entirely different when you have to face it yourself, another point of
similarity with math, the more you practice, the better you get :)
Richard, your definition of List_Or t made the coin drop in my head (since i
knew almost nothing about datatypes), and I has managed to write a little
"flatten" function for these nested lists. I am now trying to think how to
make my solution nicer (hehe dont spoil it yet by showing me yours yet! :) )
You all have a great weekend,
Vadali
On Wed, Jul 14, 2010 at 12:09 PM, Chaddaï Fouché
Thank you Bob, your example clarified how actually using such data type would appear in haskell. I naively thought it would be as simple as defining a regular
On Tue, Jul 13, 2010 at 11:28 AM, Shlomi Vaknin
wrote: list, but i see it is slightly more strict than that. I appreciate your help! Vadali
Well it _is_ as simple as defining a regular list, which would be (fictionally since (:) and [] are reserved identifiers) :
data [] a = [] | a : [a]
Which is the same as :
data List a = Empty | Cons a (List a)
You can then handle lists with pattern matching :
map f [] = [] map f (x:xs) = f x : map f xs
Or for our List type :
map f Empty = Empty map f (Cons x xs) = Cons (f x) (map f xs)
His definition of a tree :
data Tree a = Leaf | Branch a [Tree a]
follows the same idea and is as easy to handle with pattern matching :
treeMap f Leaf = Leaf treeMap f (Branch x xs) = Branch (f x) (map (treeMap f) xs)
As you see, an user defined type is manipulated with the same mechanism as a "primitive" type, this uniformity is part of the power of Haskell in that it encourages users to create their types and allows seamless integration of external library types with "primitive" types.
-- Jedaï