represent data sturcture using function

Merry Christmas! Hope everybody is enjoying the Christmas! I am doing some readings and I found something seems to be interesting. People sometime will try to represent a quantity-regard-only data structure (such a order-regadless List) using functions instead of ta concrete data structure (like the haskell build-in []), any particular reason for this? For example,
data Sex = Male | Female classA :: Sex -> Int classA Male = 100 classA Female = 200
when I should prefer the above solution instead of using a concrete data structure such as [] to represent the classA members? It seems to be very difficult to change the number of Male or Female if a concrete data structure is not used. Is it possible change the number of Male in classA when represent classA using function? Thank you very much! Best wishes, Raeck _________________________________________________________________ It’s the same Hotmail®. If by “same” you mean up to 70% faster. http://windowslive.com/online/hotmail?ocid=TXT_TAGLM_WL_hotmail_acq_broad1_1...

2008/12/29 Raeck chiu
People sometime will try to represent a quantity-regard-only data structure (such a order-regadless List) using functions instead of ta concrete data structure (like the haskell build-in []), any particular reason for this?
For example,
data Sex = Male | Female classA :: Sex -> Int classA Male = 100 classA Female = 200
when I should prefer the above solution instead of using a concrete data structure such as [] to represent the classA members?
One important difference between Sex -> Int and [(Sex,Int)] is that the first guarantees exactly one Int per Sex and has no underlying order. (That is, [(Male,100),(Female,200)] and [(Female,200),(Male,100)] are distinct lists but represent the same map.)
It seems to be very difficult to change the number of Male or Female if a concrete data structure is not used. Is it possible change the number of Male in classA when represent classA using function?
Here's the simplest way:
update k v map = \k' -> if k' == k then v else map k'
Note that it requires an Eq instance for Sex.
let classA' = update Male 150 classA
in (classA' Male, classA' Female)
=
(150,200)
--
Dave Menendez

On Sun, Dec 28, 2008 at 10:13 PM, David Menendez
2008/12/29 Raeck chiu
: It seems to be very difficult to change the number of Male or Female if a concrete data structure is not used. Is it possible change the number of Male in classA when represent classA using function?
Here's the simplest way:
update k v map = \k' -> if k' == k then v else map k'
Note that it requires an Eq instance for Sex.
let classA' = update Male 150 classA in (classA' Male, classA' Female) = (150,200)
Of course this version of update leaks crazy amounts of memory:
let bigmap = iterate (update Male 150) classA !! 100000 bigmap Male
"bigmap" leaves a huge chain of thunks pointing at each other, which can never be freed. Using functions is mathematically more elegant than some concrete data structure (which might require Eq or Ord or other constraints, and have multiple observable representations for the same map, or have maps that don't include every element). However, "generic maps" have been improving a lot recently, especially with data families in the new GHC. You use an abstract type (k :-> v) to represent the map; this type is semantically equivalent to (k -> v) via some observation function for generic maps, but has a compact representation. For example:
class MapKey k where data k :-> v newMap :: (k -> v) -> (k :-> v) fetch :: (k :-> v) -> (k -> v) update :: (k,v) -> (k :-> v) -> (k :-> v) empty :: v -> (k :-> v) empty = newMap (const v)
instance MapKey Bool where data Bool :-> v = BoolMap v v newMap f = BoolMap (f False) (f True) fetch (Boolmap t f) v = if v then t else f update (True, t) (BoolMap _ f) = Boolmap t f update (False, f) (BoolMap t _) = Boolmap t f
"fetch" converts this representation of a total function over k, into an actual function. The representation of k :-> v might vary depending on k; Int might use IntMap, (k1,k2) can compose maps:
instance (MapKey k1, MapKey k2) => MapKey (k1,k2) where newtype (k1,k2) :-> v = PairMap (k1 :-> (k2 :-> v)) ...
instance (MapKey k1, MapKey k2) => MapKey (Either k1 k2) where data (Either k1 k2) :-> v = EitherMap (k1 :-> v) (k2 :-> v) ...
This gives you the same benefits as the function approach but without the terrible performance issues. You do need to write instances for your types, though, although most can be easily derived from the instances for pairs, Either, and Integer. See http://www.haskell.org/haskellwiki/GHC/Indexed_types for more. -- ryan

Bonus points if you find the stupid bug in my code :)
-- ryan
On Mon, Dec 29, 2008 at 1:48 AM, Ryan Ingram
On Sun, Dec 28, 2008 at 10:13 PM, David Menendez
wrote: 2008/12/29 Raeck chiu
: It seems to be very difficult to change the number of Male or Female if a concrete data structure is not used. Is it possible change the number of Male in classA when represent classA using function?
Here's the simplest way:
update k v map = \k' -> if k' == k then v else map k'
Note that it requires an Eq instance for Sex.
let classA' = update Male 150 classA in (classA' Male, classA' Female) = (150,200)
Of course this version of update leaks crazy amounts of memory:
let bigmap = iterate (update Male 150) classA !! 100000 bigmap Male
"bigmap" leaves a huge chain of thunks pointing at each other, which can never be freed.
Using functions is mathematically more elegant than some concrete data structure (which might require Eq or Ord or other constraints, and have multiple observable representations for the same map, or have maps that don't include every element).
However, "generic maps" have been improving a lot recently, especially with data families in the new GHC. You use an abstract type (k :-> v) to represent the map; this type is semantically equivalent to (k -> v) via some observation function for generic maps, but has a compact representation. For example:
class MapKey k where data k :-> v newMap :: (k -> v) -> (k :-> v) fetch :: (k :-> v) -> (k -> v) update :: (k,v) -> (k :-> v) -> (k :-> v) empty :: v -> (k :-> v) empty = newMap (const v)
instance MapKey Bool where data Bool :-> v = BoolMap v v newMap f = BoolMap (f False) (f True) fetch (Boolmap t f) v = if v then t else f update (True, t) (BoolMap _ f) = Boolmap t f update (False, f) (BoolMap t _) = Boolmap t f
"fetch" converts this representation of a total function over k, into an actual function. The representation of k :-> v might vary depending on k; Int might use IntMap, (k1,k2) can compose maps:
instance (MapKey k1, MapKey k2) => MapKey (k1,k2) where newtype (k1,k2) :-> v = PairMap (k1 :-> (k2 :-> v)) ...
instance (MapKey k1, MapKey k2) => MapKey (Either k1 k2) where data (Either k1 k2) :-> v = EitherMap (k1 :-> v) (k2 :-> v) ...
This gives you the same benefits as the function approach but without the terrible performance issues. You do need to write instances for your types, though, although most can be easily derived from the instances for pairs, Either, and Integer.
See http://www.haskell.org/haskellwiki/GHC/Indexed_types for more.
-- ryan

Are there anyway to express the "iterating" of a user-defined data type in Haskell? For example, in
data Shape = Square | Circle | Triangle
how can I 'iterate' them and apply them all to the same function without indicating them explicitly? such as [func Square, func Circle, func Triangle]. Can I use a form similar to the following case in a list instead:
Numbers = [1,2,3,4,5]
[func x | x <- Numbers ]
Actually what I want is to obtain all the possible values of a data type (Shape). Thank you very much! Best wishes, Raeck

On Mon, Dec 29, 2008 at 6:24 PM,
Are there anyway to express the "iterating" of a user-defined data type in Haskell?
For example, in
data Shape = Square | Circle | Triangle
how can I 'iterate' them and apply them all to the same function without indicating them explicitly? such as [func Square, func Circle, func Triangle]. Can I use a form similar to the following case in a list instead:
Numbers = [1,2,3,4,5]
[func x | x <- Numbers ]
Actually what I want is to obtain all the possible values of a data type (Shape).
For "enum" style data, where all the constructors have no arguments, you can do deriving (Bounded, Enum), so: data Shape = Square | Circle | Triangle deriving (Bounded,Enum) Then: numbers = [minBound..maxBound] :: [Shape] Luke

You actually have two different questions. The first about iteration can be done by the function map in the following way: Instead of [func Square, func Circle, func Triangle] you use: map func [Square, Circle, Triangle]. The list comprehensions should also work: [func x | x <- [Square, Circle, Triangle]] Now as for obtaining/generating all values of Shape, the easiest way is to make Shape an instance of Enum, like this: data Shape = Square | Circle | Triangle deriving Enum You can then generate a list of all the values by: enumFrom Square You use Square here because it is the first constructor of Shape, and you want to enumerate them all. I hope this helps, Paul raeck@msn.com wrote:
Are there anyway to express the "iterating" of a user-defined data type in Haskell?
For example, in
data Shape = Square | Circle | Triangle
how can I 'iterate' them and apply them all to the same function without indicating them explicitly? such as [func Square, func Circle, func Triangle]. Can I use a form similar to the following case in a list instead:
Numbers = [1,2,3,4,5]
[func x | x <- Numbers ]
Actually what I want is to obtain all the possible values of a data type (Shape).
Thank you very much!
Best wishes,
Raeck _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Mon, Dec 29, 2008 at 4:48 AM, Ryan Ingram
On Sun, Dec 28, 2008 at 10:13 PM, David Menendez
wrote: Here's the simplest way:
update k v map = \k' -> if k' == k then v else map k'
Of course this version of update leaks crazy amounts of memory:
let bigmap = iterate (update Male 150) classA !! 100000 bigmap Male
"bigmap" leaves a huge chain of thunks pointing at each other, which can never be freed.
Sure. It's slow, too. If you want a map that you can update, you're
usually much better off with a concrete data structure.
--
Dave Menendez
participants (6)
-
David Menendez
-
Luke Palmer
-
Paul Visschers
-
Raeck chiu
-
raeck@msn.com
-
Ryan Ingram