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. Re: recursion and pattern matching (Alia)
2. Re: using record in aeson (Rick Murphy)
3. Re: Ord and Eq instances for complex types (Mike Meyer)
4. Re: Data-List-Utils (David McBride)
5. Re: Data-List-Utils (CEO'Riley)
6. Re: recursion and pattern matching (Brent Yorgey)
7. Re: Data-List-Utils (David McBride)
----------------------------------------------------------------------
Message: 1
Date: Tue, 18 Oct 2011 17:12:50 -0700 (PDT)
From: Alia <[email protected]>
Subject: Re: [Haskell-beginners] recursion and pattern matching
To: "[email protected]" <[email protected]>
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=iso-8859-1
[apologies if this is a duplicate, as my prior communication may or may not be
lost in the ether]
Ok, so having spent some further time on this. Methinks I have a solution below.
The aha moment occurred when I fell upon the definition of foldr and then
looked at
the recursive functions.
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f z []???? = z
foldr f z (x:xs) = f x (foldr f z xs)
treeFold is implemented two ways, the first is as Brent advised, the second
places
the accumulator after the function and follows from foldr. I suspect the first
approach
is probably more practical because you can curry the accumulator away.
The final check function verifies the equivalence of recursive and fold
friendly functions.
It was a cool exercise in all. Thanks Brent! (-:?
AK
<Test.hs>
module Test
where
data Tree a b = EmptyTree | Node a b [Tree a b]
????????????? deriving (Show, Read, Eq)?
t =? Node "goal" 1.0 [
??????? Node "a2" 0.5 [
??????????? Node "a3" 3.0 [
??????????????? Node "a4" 1.0 [
??????????????????? Node "a5" 1.0 []
??????????????????? ]
??????????????? ]
??????????? ],
??????? Node "b2" 0.5 [
??????????? Node "b3.1" 2.0 [],
??????????? Node "b3.2" 2.0 [
??????????????? Node "b4" 10.0 []
??????????????? ]
??????????? ]
???? ]
maximum0 [] = 0
maximum0 xs = maximum xs
sumTree :: (Num b) => Tree a b -> b
sumTree EmptyTree = 0
sumTree (Node _ value children) = value + sum (map sumTree children)
count :: Tree a b -> Int
count EmptyTree = 0
count (Node _ value children) = 1 + sum (map count children)
depth :: Tree a b -> Int
depth EmptyTree = 0
depth (Node _ value children) = 1 + maximum0 (map depth children)
treeFold :: c -> (a -> b -> [c] -> c) -> Tree a b -> c
treeFold acc f EmptyTree = acc
treeFold acc f (Node name value children) = f name value (map (treeFold acc f)
children)
treeFold' :: (a -> b -> [c] -> c) -> c -> Tree a b -> c
treeFold' f z EmptyTree = z
treeFold' f z (Node name value children) = f name value (map (treeFold' f z)
children)
sumTree' :: String -> Double -> [Double] -> Double
sumTree' name value xs = value + sum xs
count' :: (Num c) => a -> b -> [c] -> c
count' name value xs = 1 + sum xs
depth' :: (Num c, Ord c) => a -> b -> [c] -> c
depth' name value xs = 1 + maximum0 (xs)
check = [ count t? ? ?? == treeFold' count' 0 t
???????????? , sumTree t? == treeFold' sumTree' 0 t
???????????? , depth t? ? ?? == treeFold' depth' 0 t
???????????? ]
<Test.hs>
------------------------------
Message: 2
Date: Tue, 18 Oct 2011 20:23:43 -0400
From: Rick Murphy <[email protected]>
Subject: Re: [Haskell-beginners] using record in aeson
To: beginners <[email protected]>
Cc: [email protected]
Message-ID: <1318983823.6764.20.camel@metho-laptop>
Content-Type: text/plain; charset="UTF-8"
Thanks, David. That was great advice.
I wonder whether you and others might provide more advice on how to
improve the worked example below. I suspect the compiler provides a hint
with the pattern match overlap warning, but I wonder what opportunities
for refactoring an experienced Haskeller would envision.
In terms of background, the worked example partially implements the
following specification.
http://docs.api.talis.com/platform-api/output-types/rdf-json
Here's a test string and the worked example:
{"http://www.example.com/about":{"http://purl.org/dc/elements/1.1/title":{"type":"literal","value":"Rick's
Home
Page","lang":"http://w3.org/en","datatype":"http://w3.org/#string"},"http://purl.org/dc/elements/1.1/title":{"type":"literal","value":"Rick's
Home Page","lang":"http://w3.org/en","datatype":"http://w3.org/#string"}}}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Applicative
import Control.Monad (mzero)
import qualified Data.ByteString as B
import qualified Data.Map as M
import qualified Data.Text as T
import Data.Aeson
import qualified Data.Aeson.Types as J
import Data.Attoparsec
data RDFType = Literal T.Text | URI T.Text | BNode T.Text deriving
(Show)
type RDFValue = T.Text
type Lang = T.Text
type DTyp = T.Text
data RDFObject = RDFObject {s :: RDFType, u :: RDFValue, v :: Lang, w ::
DTyp} deriving (Show)
data Property = Property (T.Text, RDFObject) deriving (Show)
data Subject = Subject (T.Text, [Property]) deriving (Show)
data RDF = RDF [Subject] deriving Show
instance FromJSON Subject
where
parseJSON (Object o) = Subject <$> toSubject o
where
toSubject :: (M.Map T.Text Value) -> J.Parser (T.Text,
[Property])
toSubject o' = do
s <- return $ M.assocs o'
k <- return $ fst $ head s
v <- return $ snd $ head s
ps <- mapM (parseJSON :: Value -> J.Parser Property) (M.elems
o')
return $ (k,ps)
toSubject _ = error "unexpected subject"
parseJSON _ = mzero
instance FromJSON RDFObject where
parseJSON (Object o) = RDFObject <$> (o .: "type") <*> (o .: "value")
<*> (o .: "lang") <*> (o .: "datatype")
instance FromJSON Property where
parseJSON (Object o) = Property <$> toProperty o
where
toProperty :: (M.Map T.Text Value) -> J.Parser (T.Text, RDFObject)
toProperty o' = do
p <- return $ M.assocs o'
k <- return $ fst $ head p
v <- return $ snd $ head p
o'' <- parseJSON v :: J.Parser RDFObject
return (k,o'')
toProperty _ = error "unexpected property"
parseJSON _ = mzero
instance FromJSON RDFType where
parseJSON v@(String s) | v == "literal" = return $ Literal s
| v == "bnode" = return $ BNode s
| otherwise = return $ URI s
parseAll :: B.ByteString -> [Subject]
parseAll s = case (parse (fromJSON <$> json) s) of
Done _ (Error err) -> error err
Done ss (Success e) -> e:(parseAll ss)
_ -> []
main :: IO ()
main = do s <- B.readFile "6.json"
let p = RDF $ parseAll s
print p
--
Rick
On Wed, 2011-10-12 at 11:21 -0400, David McBride wrote:
> The problem is that in parseObject, from the moment you type 'return',
> you are then in pure code. But you are trying to do applicative
> functions as if you are still in the Parser monad. Here is a way to
> rewrite this.
>
> First rewrite
> data MyRecord = MyRecord {s :: T.Text, u :: T.Text} deriving (Show)
> because we are using Text not String, then
>
> parseObject o' = mapM toMyPair (M.assocs o')
> where
> toMyPair :: (T.Text, Value) -> J.Parser MyPair
> toMyPair (t, Object o'') = do
> rec <- MyRecord <$> (o'' .: "type") <*> (o'' .: "value") ::
> J.Parser MyRecord
> return $ R (t, rec)
> toMyPair _ = error "unexpected"
>
> That is, stay in the parser monad and pull out the things you need
> using do notation, then return the whole thing back into the parser
> monad. You could have also gone:
>
> toMyPair (t, Object o'') = do
> typ <- o'' .: "type"
> val <- o'' .: "value"
> return $ R (t, MyRecord typ val)
>
>
> On Tue, Oct 11, 2011 at 9:17 PM, Rick Murphy <[email protected]> wrote:
> > Hi All:
> >
> > I've been elaborating on aeson examples and wondered whether someone
> > could clarify the syntax for using a record in a pair. My goal is to
> > substitute a record for the list of pairs created through the data
> > constructor O [(T.Text, Value)] in MyPair below. Reason being to embed
> > the semantics of the json file into the record. To reproduce, just
> > uncomment the lines in the source below.
> >
> > The json file structure is as follows:
> > {"outer":{"type":"literal","value":"rick"}}
> >
> > Note my naive attempt in the commented lines returns the following
> > message from ghci. 'f0 b0' doesn't give me much to go on.
> >
> > -- E1.hs:35:41:
> > -- Couldn't match expected type `MyRecord' with actual type `f0 b0'
> > -- In the expression: MyRecord <$> o'' .: "type" <*> o'' .: "value"
> > -- In the first argument of `R', namely
> > -- `(t, MyRecord <$> o'' .: "type" <*> o'' .: "value")'
> > -- In the expression: R (t, MyRecord <$> o'' .: "type" <*> o'' .:
> > "value")
> > -- Failed, modules loaded: none.
> >
> > {-# LANGUAGE OverloadedStrings #-}
> >
> > module Main where
> >
> > import Control.Applicative
> > import Control.Monad (mzero)
> >
> > import qualified Data.ByteString as B
> > import qualified Data.Map as M
> > import qualified Data.Text as T
> >
> > import Data.Aeson
> > import qualified Data.Aeson.Types as J
> > import Data.Attoparsec
> >
> > -- data MyRecord = MyRecord {s :: String, u :: String} deriving (Show)
> >
> > data MyPair = O (T.Text, [(T.Text, Value)])
> > -- | R (T.Text, MyRecord)
> > deriving (Show)
> >
> > data ExifObject = ExifObject [MyPair]
> > deriving Show
> >
> > data Exif = Exif [ExifObject]
> > deriving Show
> >
> > instance FromJSON ExifObject
> > where
> > parseJSON (Object o) = ExifObject <$> parseObject o
> > where
> > parseObject o' = return $ map toMyPair (M.assocs o')
> >
> > toMyPair (t, Object o'')= O (t, M.assocs o'')
> > -- toMyPair (t, Object o'')= R (t, MyRecord <$> o'' .: "type" <*>
> > o'' .: "value")
> > toMyPair _ = error "unexpected"
> >
> > parseJSON _ = mzero
> >
> > parseAll :: B.ByteString -> [ExifObject]
> > parseAll s = case (parse (fromJSON <$> json) s) of
> > Done _ (Error err) -> error err
> > Done ss (Success e) -> e:(parseAll ss)
> > _ -> []
> >
> > main :: IO ()
> > main = do s <- B.readFile "e1.json"
> > let p = Exif $ parseAll s
> > print p
> >
> > --
> > Rick
> >
> >
> > _______________________________________________
> > Beginners mailing list
> > [email protected]
> > http://www.haskell.org/mailman/listinfo/beginners
> >
>
------------------------------
Message: 3
Date: Tue, 18 Oct 2011 17:29:24 -0700
From: Mike Meyer <[email protected]>
Subject: Re: [Haskell-beginners] Ord and Eq instances for complex
types
To: Daniel Fischer <[email protected]>
Cc: [email protected]
Message-ID:
<CAD=7u2dz90zq2d1hsr4ucrzmxnp+4mshv1f7bcgdv-a_uok...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"
Ok, *this* works just fine:
data Hand = HighCard {cards :: [Card]}
| PairOf {rank1 :: Rank, cards :: [Card]}
| TwoPair {rank1, rank2 ::Rank, cards :: [Card]}
| ThreeOfAKind {rank1 :: Rank, cards :: [Card]}
| Straight {cards :: [Card]}
| Flush {cards :: [Card]}
| FullHouse {rank1, rank2 :: Rank, cards :: [Card]}
| FourOfAKind {rank1 :: Rank, cards :: [Card]}
| StraightFlush {cards :: [Card]}
deriving (Show, Eq, Ord)
The derived order is actually correct - providing, again, that the hands are
well-formed (which the unshown constructor makeHand :: [Cards] -> Hand
insures). The only writeup I could find for deriving Ord for datatypes was
the report. Anyone got a better pointer to one?
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20111018/d5fcc900/attachment-0001.htm>
------------------------------
Message: 4
Date: Tue, 18 Oct 2011 20:38:08 -0400
From: David McBride <[email protected]>
Subject: Re: [Haskell-beginners] Data-List-Utils
To: [email protected]
Cc: [email protected]
Message-ID:
<CAN+Tr41Tt4Q=CtbkUphgoqZ=uxd+1cprhzmfjmlm0jemrab...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
Data.List.Utils is part of the missingh library. If your app can't
find it, it is probably not installed. cabal install missingh.
To find out where a random import comes from, go to
hackage.haskell.org, click on hayoo, and search for "Data.List.Utils".
The ambiguous module name is totally different and doesn't happen very
often anymore. Monads-fd used to be an improved version of mtl, and
it exported roughly the same interface, but monads-fd is now
deprecated and shouldn't be used. Sometimes when you load a file it
ends up choosing it anyways, because it has to choose something. You
can avoid that by typing ghci -hide-package=monads-fd. Alternatively
you can use ghc-pkg hide to hide it permanently, so that nothing tries
to use that, that should work.
------------------------------
Message: 5
Date: Tue, 18 Oct 2011 20:15:53 -0500
From: "CEO'Riley" <[email protected]>
Subject: Re: [Haskell-beginners] Data-List-Utils
To: <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"
Hi David,
Thanks for responding. I'm out here at the hackage.haskell.org site and
performed the search. I guess my first question here would be "what is
missing"? Does this mean something is missing? I see it for a lot of the
components (functions) of Data.List.Utils.
Regards,
CEO'Riley
Charles E. O'Riley Jr.
-----Original Message-----
From: David McBride [mailto:[email protected]]
Sent: Tuesday, October 18, 2011 7:38 PM
To: [email protected]
Cc: [email protected]
Subject: Re: [Haskell-beginners] Data-List-Utils
Data.List.Utils is part of the missingh library. If your app can't find it,
it is probably not installed. cabal install missingh.
To find out where a random import comes from, go to hackage.haskell.org,
click on hayoo, and search for "Data.List.Utils".
The ambiguous module name is totally different and doesn't happen very often
anymore. Monads-fd used to be an improved version of mtl, and it exported
roughly the same interface, but monads-fd is now deprecated and shouldn't be
used. Sometimes when you load a file it ends up choosing it anyways,
because it has to choose something. You can avoid that by typing ghci
-hide-package=monads-fd. Alternatively you can use ghc-pkg hide to hide it
permanently, so that nothing tries to use that, that should work.
------------------------------
Message: 6
Date: Tue, 18 Oct 2011 21:34:42 -0400
From: Brent Yorgey <[email protected]>
Subject: Re: [Haskell-beginners] recursion and pattern matching
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=iso-8859-1
On Tue, Oct 18, 2011 at 05:04:10PM -0700, Alia wrote:
> Ok, so having spent some further time on this. Methinks I have a solution
> below.
>
> The aha moment occurred when I fell upon the definition of foldr and then
> looked at
> the recursive functions.
>
>
> foldr :: (a -> b -> b) -> b -> [a] -> b
> foldr f z []???? = z
> foldr f z (x:xs) = f x (foldr f z xs)
>
> treeFold is implemented two ways, the first is as Brent advised, the second
> places
> the accumulator after the function and follows from foldr. I suspect the
> first approach
> is probably more practical because you can curry the accumulator
> away.
I don't think it makes a big difference which way you order the
arguments. Since there is one argument for each constructor of Tree,
I just like having the arguments in the same order as the constructors
in the definition. But it's not really important.
> It was a cool exercise in all. Thanks Brent! (-:?
Glad you enjoyed it! Nicely done!
-Brent
------------------------------
Message: 7
Date: Wed, 19 Oct 2011 01:30:50 -0400
From: David McBride <[email protected]>
Subject: Re: [Haskell-beginners] Data-List-Utils
To: [email protected]
Cc: [email protected]
Message-ID:
<can+tr41qv_ne4ly8vgedmzmjo-j0o9ykpdh-xh2ppxttbon...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
I'm sorry, the name of the library you are missing is called,
coincidentally, "missingH" so, the command 'cabal install missingh'
*should* solve your problem and allow you to build that package. No,
I have no idea why they called it that. Hmm, looked it up, it is a
big library of functions that the author deemed were missing in
haskell. Anyways, it is used quite a bit.
There may be other libraries you are missing, all of which are up on
hackage, and if you aren't sure where a certain import or function
comes from you can look it up in hayoo and get more information about
it.
On Tue, Oct 18, 2011 at 9:15 PM, CEO'Riley <[email protected]> wrote:
> Hi David,
>
> Thanks for responding. ?I'm out here at the hackage.haskell.org site and
> performed the search. ?I guess my first question here would be "what is
> missing"? ?Does this mean something is missing? ?I see it for a lot of the
> components (functions) of Data.List.Utils.
>
>
>
> Regards,
> CEO'Riley
> Charles E. O'Riley Jr.
>
>
> -----Original Message-----
> From: David McBride [mailto:[email protected]]
> Sent: Tuesday, October 18, 2011 7:38 PM
> To: [email protected]
> Cc: [email protected]
> Subject: Re: [Haskell-beginners] Data-List-Utils
>
> Data.List.Utils is part of the missingh library. ?If your app can't find it,
> it is probably not installed. ?cabal install missingh.
>
> To find out where a random import comes from, go to hackage.haskell.org,
> click on hayoo, and search for "Data.List.Utils".
>
> The ambiguous module name is totally different and doesn't happen very often
> anymore. ?Monads-fd used to be an improved version of mtl, and it exported
> roughly the same interface, but monads-fd is now deprecated and shouldn't be
> used. ?Sometimes when you load a file it ends up choosing it anyways,
> because it has to choose something. ?You can avoid that by typing ?ghci
> -hide-package=monads-fd. ?Alternatively you can use ghc-pkg hide to hide it
> permanently, so that nothing tries to use that, that should work.
>
>
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 40, Issue 31
*****************************************