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
*****************************************

Reply via email to