Re: [Haskell-cafe] represent data sturcture using function

On Mon, Dec 29, 2008 at 4:29 AM,
Would you please give me a complete example of code that I could have more information on the idea?
Sure, I put up an example at http://ryani.freeshell.org/haskell/gmap.hs class MapKey k where data (:->) k :: * -> * newMap :: (k -> v) -> (k :-> v) fetch :: (k :-> v) -> (k -> v) update :: k -> (v -> v) -> (k :-> v) -> (k :-> v) assign :: k -> v -> (k :-> v) -> (k :-> v) assign k v m = update k (const v) m empty :: v -> (k :-> v) empty = newMap . const with instances & associated data types: instance MapKey () where -- A single value newtype () :-> v = UMap v instance MapKey Bool where -- A value for False and True data Bool :-> v = BMap v v instance (MapKey k1, MapKey k2) => MapKey (k1,k2) where -- A "curried" map newtype (k1,k2) :-> v = PMap (k1 :-> k2 :-> v) instance (MapKey k1, MapKey k2) => MapKey (Either k1 k2) where -- sub-maps for Left k1 and Right k2 data (Either k1 k2 :-> v) = EMap (k1 :-> v) (k2 :-> v) instance MapKey k => MapKey (Maybe k) where -- Now we can build up from existing structures! newtype (Maybe k) :-> v = MaybeM (Either () k :-> v) instance MapKey k => MapKey [k] where -- Value for [] and map for (head:tail) -- -- Note that this includes a recursive ([k] :-> v) map -- in the pair map (k,[k]) :-> v data [k] :-> v = ListM v ((k,[k]) :-> v) instance MapKey Positive where -- We just convert a positive number into -- a list of Bools, then make a map of those newtype Positive :-> v = PosMap ([Bool] :-> v) instance MapKey Integer where -- Now an integer is either negative, zero, or positive. -- So we store a map for negative numbers, a zero value, -- and a map for positive numbers. data Integer :-> v = IntMap (Positive :-> v) v (Positive :-> v) The rest of the class functions are reasonably easy to derive from their type and these data types. -- ryan

Hi, how can I make the following code work? (show all the possible values of a type 'a')
showAll :: (Eq a, Bounded a, Enum a) => a -> [a] showAll a = [minBound..maxBound]::[a]
it keeps saying that I could fix the problem by adding (Enum a) and (Bounded a) the the context, but I failed when I try. anything goes wrong? Thanks! Raeck

[-cafe left out] On Tue, 2008-12-30 at 17:12 +0000, raeck@msn.com wrote:
Hi, how can I make the following code work? (show all the possible values of a type 'a')
showAll :: (Eq a, Bounded a, Enum a) => a -> [a] showAll a = [minBound..maxBound]::[a]
it keeps saying that I could fix the problem by adding (Enum a) and (Bounded a) the the context, but I failed when I try.
The problem is the inner annotation, ::[a]. It's not the same a as in
(Eq a, Bounded a, Enum a) => a -> [a], and in Haskell98 it can't be. I'm
not surprised that's confused you! If you remove the inner annotation it
should work fine though.
You can go a step further and make showAll a value rather than a
function:
showAll = [minBound..maxBound]
(I've left out the type annotations, but you can put ":t
[minBound..maxBound]" into ghci or hugs if you want one)
--
Philippa Cowderoy

You seem to be having some trouble with the type system, not just in this instance. I found when I was learning Haskell that when this happens, it is useful to not add type annotations, then load it up in GHCi and see what it comes up with (with the aforementions :t option). Then you can see why that makes sense and possibly change the function. Once you're happy with the function and are confident you understand its type, go ahead and put the type annotation back into your source code. I also found it useful to play around with various expressions and see what their types where. Especially with things like partial application, function composition and monadic functions. Paul Philippa Cowderoy wrote:
[-cafe left out]
On Tue, 2008-12-30 at 17:12 +0000, raeck@msn.com wrote:
Hi, how can I make the following code work? (show all the possible values of a type 'a')
showAll :: (Eq a, Bounded a, Enum a) => a -> [a] showAll a = [minBound..maxBound]::[a] it keeps saying that I could fix the problem by adding (Enum a) and (Bounded a) the the context, but I failed when I try.
The problem is the inner annotation, ::[a]. It's not the same a as in (Eq a, Bounded a, Enum a) => a -> [a], and in Haskell98 it can't be. I'm not surprised that's confused you! If you remove the inner annotation it should work fine though.
You can go a step further and make showAll a value rather than a function:
showAll = [minBound..maxBound]
(I've left out the type annotations, but you can put ":t [minBound..maxBound]" into ghci or hugs if you want one)

On Tue, 2008-12-30 at 17:12 +0000, raeck@msn.com wrote:
Hi, how can I make the following code work? (show all the possible values of a type 'a')
showAll :: (Eq a, Bounded a, Enum a) => a -> [a] showAll a = [minBound..maxBound]::[a]
The bottom 'a' has nothing to do with the 'a' in the type signature. Your code is equivalent to
showAll :: (Eq a, Bounded a, Enum a) => a -> [a] showAll a = [minBound..maxBound]::[b]
Which is not type correct as [minBound..maxBound] :: (Bounded a, Enum a) => [a] You don't need that type annotation (or the type signature for that matter), so just omit it.

Raeck said:
Hi, how can I make the following code work? (show all the possible values of a type 'a')
showAll :: (Eq a, Bounded a, Enum a) => a -> [a] showAll a = [minBound..maxBound]::[a]
What you are really looking for, I think, is a polymorphic value of type [a], where a is some enumerable, bounded type. allValues :: (Enum a, Bounded a) => [a] allValues = [minBound .. maxBound] You can omit the type signature, but then you'll run into the monomorphism restriction (which you'll can turn off with, e.g. -XNoMonomorphismRestriction)
participants (6)
-
Derek Elkins
-
Paul Visschers
-
Philippa Cowderoy
-
raeck@msn.com
-
Robert Greayer
-
Ryan Ingram