Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. How do I define data types with arbitrary content?
(Alexander Raasch)
2. Re: How do I define data types with arbitrary content?
(Daniel Fischer)
3. Implementing Read (Peter Hall)
4. Re: Implementing Read (Daniel Fischer)
5. Re: Implementing Read (Peter Hall)
6. Re: Implementing Read (Daniel Fischer)
7. Re: Implementing Read (Peter Hall)
8. Re: Implementing Read (Sean Perry)
9. error handling approaches (Michael Litchard)
----------------------------------------------------------------------
Message: 1
Date: Sun, 11 Sep 2011 14:21:10 +0200
From: Alexander Raasch <[email protected]>
Subject: [Haskell-beginners] How do I define data types with arbitrary
content?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Hi,
just for the sake of deepening my understanding of Haskell types, I'm
looking for a way to define a data type, like list or tree, that takes
arbitrary values as its content.
In Java, I would write
class Tree { Object node; Tree left; Tree right; }
and that allows me to put Integers, Strings, or anything into the tree,
since they all inherit from Object. How would I go about defining such a
type in Haskell?
I'm reading www.learnyouahasell.com and all of the examples use only a
single type parameter as in
data Tree a = Nil | Node a (Tree a) (Tree a)
so you can't mix Integers and Strings for example.
Alex
------------------------------
Message: 2
Date: Sun, 11 Sep 2011 15:27:01 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] How do I define data types with
arbitrary content?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: Text/Plain; charset="iso-8859-1"
On Sunday 11 September 2011, 14:21:10, Alexander Raasch wrote:
> Hi,
>
> just for the sake of deepening my understanding of Haskell types, I'm
> looking for a way to define a data type, like list or tree, that takes
> arbitrary values as its content.
>
> In Java, I would write
>
> class Tree { Object node; Tree left; Tree right; }
>
> and that allows me to put Integers, Strings, or anything into the tree,
> since they all inherit from Object. How would I go about defining such a
> type in Haskell?
In general, you don't. Such a structure would be pretty useless, since one
couldn't call any interesting functions on the values it contains.
If you're absolutely determined to do it, there are ways, but really,
please don't.
If you don't want the full generality of being able to put *anything* in
your tree (and you probably don't), there are sufficiently nice ways of
doing something like that.
>
> I'm reading www.learnyouahasell.com and all of the examples use only a
> single type parameter as in
>
> data Tree a = Nil | Node a (Tree a) (Tree a)
>
> so you can't mix Integers and Strings for example.
Yes, there are different operations for Strings and Integers, so that
prevents calling e.g. ("Hello" ^ "world") or (tail 5).
Hence it is a good thing.
Generally, you have a (small) set of types you're interested in, then you
can define a type
data Wrapper
= I Integer
| S String
| B Bool
...
and use that to wrap your values; or you're interested in types supporting
some specific operations, then you can use an existential wrapper:
{-# LANGUAGE ExistentialQuantification #-}
data Foo = forall a. (Class1 a, Class2 a) => Foo a
Then you use (Tree Foo) and wrap your values in a Foo to put them in the
tree. You can then use the methods of Class1 and Class2 on the values
(more conveniently if you define instances of Class1 and Class2 for Foo
instance Class1 Foo where
method (Foo x) = method x
...
that's somewhat similar to Java interfaces), but only those.
------------------------------
Message: 3
Date: Sun, 11 Sep 2011 19:32:32 +0100
From: Peter Hall <[email protected]>
Subject: [Haskell-beginners] Implementing Read
To: [email protected]
Message-ID:
<CAA6hAk6VK9pKw_-G+QvZ29ubgS_LvDX12m4xzetS1kQ=8-s...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
I'm having some trouble defining an implementation for "Read". I know
I could model a card more simply as an unconstrained tuplet, but I'm
trying to learn new things about haskell as I go.
module Card.Card (
Suit(..)
,Card(..)
) where
data Suit = Club | Spade | Diamond | Heart
deriving (Eq, Ord, Show, Read, Bounded, Enum)
data Card = Card { suit :: Suit
, rank :: Int
}
deriving (Ord, Bounded, Eq)
instance Show Card where
show Card { suit = Club, rank = a } = show a ++ "c"
show Card { suit = Spade, rank = a } = show a ++ "s"
show Card { suit = Heart, rank = a } = show a ++ "h"
show Card { suit = Diamond, rank = a } = show a ++ "d"
instance Read Card where
readsPrec (a:b) = Card{ suit=(toSuit a), rank=(read b) }
where
toSuit s
| s=='c' = Club
| s=='s' = Spade
| s=='d' = Diamond
| s=='h' = Heart
The error is:
Card/Card.hs:24:12:
Couldn't match expected type `Int' against inferred type `[a]'
In the pattern: a : b
In the definition of `readsPrec':
readsPrec (a : b)
= Card {suit = (toSuit a), rank = (read b)}
where
toSuit s | s == 'c' = Club
| s == 's' = Spade
| s == 'd' = Diamond
| s == 'h' = Heart
In the instance declaration for `Read Card'
Where am I going wrong?
Thanks,
Peter
------------------------------
Message: 4
Date: Sun, 11 Sep 2011 21:05:11 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Implementing Read
To: [email protected], [email protected]
Message-ID: <[email protected]>
Content-Type: Text/Plain; charset="iso-8859-1"
On Sunday 11 September 2011, 20:32:32, Peter Hall wrote:
> instance Show Card where
> show Card { suit = Club, rank = a } = show a ++ "c"
> show Card { suit = Spade, rank = a } = show a ++ "s"
> show Card { suit = Heart, rank = a } = show a ++ "h"
> show Card { suit = Diamond, rank = a } = show a ++ "d"
>
>
> instance Read Card where
> readsPrec (a:b) = Card{ suit=(toSuit a), rank=(read b) }
> where
> toSuit s
>
> | s=='c' = Club
> | s=='s' = Spade
> | s=='d' = Diamond
> | s=='h' = Heart
>
> The error is:
> Card/Card.hs:24:12:
> Couldn't match expected type `Int' against inferred type `[a]'
> In the pattern: a : b
> In the definition of `readsPrec':
> readsPrec (a : b)
> = Card {suit = (toSuit a), rank = (read b)}
> where
> toSuit s | s == 'c' = Club
>
> | s == 's' = Spade
> | s == 'd' = Diamond
> | s == 'h' = Heart
>
> In the instance declaration for `Read Card'
>
>
>
> Where am I going wrong?
readsPrec takes a precedence level as first argument (to determine whether
parentheses are necessary).
If you want to ignore that for the moment, changing your definition to
readsprec _ (a:b) = ...
should work.
However, you show cards in the order rank, suit, but you read them suit,
rank. It would be better to be consistent with read and show (so that
read (show x) == x).
------------------------------
Message: 5
Date: Sun, 11 Sep 2011 22:27:53 +0100
From: Peter Hall <[email protected]>
Subject: Re: [Haskell-beginners] Implementing Read
To: Daniel Fischer <[email protected]>
Cc: [email protected]
Message-ID:
<CAA6hAk45gajVQ_gJ5FBM6N=CgywTV=05n3tj8fn4x-2tqtn...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
Thanks,
Good spot on the order. I'll get to that, but I still didn't have
success with your other suggestion.
readsPrec _ (a:b) = Card{ suit=(toSuit a), rank=(read b) }
The error is:
Card/Card.hs:24:21:
Couldn't match expected type `[(Card, String)]'
against inferred type `Card'
In the expression: Card {suit = (toSuit a), rank = (read b)}
In the definition of `readsPrec':
readsPrec _ (a : b)
= Card {suit = (toSuit a), rank = (read b)}
where
toSuit s | s == 'c' = Club
| s == 's' = Spade
| s == 'd' = Diamond
| s == 'h' = Heart
In the instance declaration for `Read Card'
Peter
On Sun, Sep 11, 2011 at 8:05 PM, Daniel Fischer
<[email protected]> wrote:
> On Sunday 11 September 2011, 20:32:32, Peter Hall wrote:
>> instance Show Card where
>> ? ? ? show Card { suit = Club, rank = a } = show a ++ "c"
>> ? ? ? show Card { suit = Spade, rank = a } = show a ++ "s"
>> ? ? ? show Card { suit = Heart, rank = a } = show a ++ "h"
>> ? ? ? show Card { suit = Diamond, rank = a } = show a ++ "d"
>>
>>
>> instance Read Card where
>> ? ? ? readsPrec (a:b) = Card{ suit=(toSuit a), rank=(read b) }
>> ? ? ? ? ? ? ? where
>> ? ? ? ? ? ? ? toSuit s
>>
>> ? ? ? ? ? ? ? ? ? ? ? | s=='c' = Club
>> ? ? ? ? ? ? ? ? ? ? ? | s=='s' = Spade
>> ? ? ? ? ? ? ? ? ? ? ? | s=='d' = Diamond
>> ? ? ? ? ? ? ? ? ? ? ? | s=='h' = Heart
>>
>> The error is:
>> Card/Card.hs:24:12:
>> ? ? Couldn't match expected type `Int' against inferred type `[a]'
>> ? ? In the pattern: a : b
>> ? ? In the definition of `readsPrec':
>> ? ? ? ? readsPrec (a : b)
>> ? ? ? ? ? ? ? ? ? ? = Card {suit = (toSuit a), rank = (read b)}
>> ? ? ? ? ? ? ? ? ? ? where
>> ? ? ? ? ? ? ? ? ? ? ? ? toSuit s | s == 'c' = Club
>>
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| s == 's' = Spade
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| s == 'd' = Diamond
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| s == 'h' = Heart
>>
>> ? ? In the instance declaration for `Read Card'
>>
>>
>>
>> Where am I going wrong?
>
> readsPrec takes a precedence level as first argument (to determine whether
> parentheses are necessary).
>
> If you want to ignore that for the moment, changing your definition to
>
> ? ?readsprec _ (a:b) = ...
>
> should work.
>
> However, you show cards in the order rank, suit, but you read them suit,
> rank. It would be better to be consistent with read and show (so that
> read (show x) == x).
>
>
>
------------------------------
Message: 6
Date: Sun, 11 Sep 2011 23:56:12 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Implementing Read
To: [email protected]
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: Text/Plain; charset="iso-8859-1"
On Sunday 11 September 2011, 23:27:53, Peter Hall wrote:
> Thanks,
> Good spot on the order. I'll get to that, but I still didn't have
> success with your other suggestion.
Oops, yes.
readsPrec returns a list of pairs, [(parsed value, remaining input)],
so
readsPrec _ (a:b) =
[(Card{suit = toSuit a, rank = r}, trl) | (r, trl) <- reads b]
where
toSuit 'c' = Club
...
------------------------------
Message: 7
Date: Sun, 11 Sep 2011 22:58:52 +0100
From: Peter Hall <[email protected]>
Subject: Re: [Haskell-beginners] Implementing Read
To: Daniel Fischer <[email protected]>
Cc: [email protected]
Message-ID:
<caa6hak4eejerbdgh7cowkup5z-njndnlfnz4gcgyzzoznft...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
Thanks, I was just responding, with:
readsPrec _ (b:a:rest) = [(Card{ suit=(toSuit a), rank=(read [b]) },
rest)]
Thanks for your help!
Peter
On Sun, Sep 11, 2011 at 10:56 PM, Daniel Fischer
<[email protected]> wrote:
> On Sunday 11 September 2011, 23:27:53, Peter Hall wrote:
>> Thanks,
>> Good spot on the order. I'll get to that, but I still didn't have
>> success with your other suggestion.
>
> Oops, yes.
>
> readsPrec returns a list of pairs, [(parsed value, remaining input)],
>
> so
>
> readsPrec _ (a:b) =
> ? ?[(Card{suit = toSuit a, rank = r}, trl) | (r, trl) <- reads b]
> ?where
> ? ?toSuit 'c' = Club
> ? ?...
>
------------------------------
Message: 8
Date: Sun, 11 Sep 2011 15:21:00 -0700
From: Sean Perry <[email protected]>
Subject: Re: [Haskell-beginners] Implementing Read
To: [email protected]
Cc: [email protected], Daniel Fischer
<[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
I see this has been answered, but since someone else may be learning too I
thought I would share.
I have always used deriving for Read so I was unsure. This post gave me the
push to go hunt it down. A very quick grep for "instance Read" in the ghc lib
sources and I found:
instance Read Int64 where
readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
In the Int.hs source. The other ints are similar. So like Daniel I ended up
with a definition based on reads once I experimented quickly.
------------------------------
Message: 9
Date: Sun, 11 Sep 2011 16:48:49 -0700
From: Michael Litchard <[email protected]>
Subject: [Haskell-beginners] error handling approaches
To: [email protected]
Message-ID:
<CAEzeKYpiWfvq6CrAq62d-AD=VjFzbCsgJEStvQod=w6be5d...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
Here's the gist of the code I am looking to incorporate error handling into
> worldHandler :: ProcessState -> JobCount -> IO ()
> worldHandler world jCount = do
> putStrLn "Entered worldHandler"
> jcount <- takeMVar jCount
> if jcount > 0
> then incrementThenDone jcount
> else doJobProcessing jcount
> where incrementThenDone jcount = do
> putMVar jCount (jcount+1)
> doJobProcessing jcount = do
> putMVar jCount (jcount+1)
> preProcess world
> initiateJob world
> makeChart world
Here's main
> main :: IO ()
> main = do
> world <- (newEmptyMVar :: IO ProcessState)
> jCount <- (newMVar 0 :: IO JobCount)
> installHandler userDefinedSignal1 (Catch $ worldHandler world jCount)
> Nothing
> forever (threadDelay 10000)
the functions preProcess, initiateJob, and makeChart is where I need
be concerned with errors. The idea is that if any of those functions
fail, I decrement jCount. call logError, and continue waiting for the
next signal.
each of these functions will be starting another process,
readProcessWithExitCode looks like what I want. I will then use the
exit code to determine success or failure.
General ideas about how to approach this, and any questions that come
to mind would be appreciated.
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 39, Issue 12
*****************************************