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 : Re: [Haskell-beginners] Compile type Error
      (emmanuel.delaborde)
   2. Re:  Compile type Error (Daniel Fischer)
   3. Re:  Compile type Error (Daniel Fischer)
   4.  Understanding cached fibonnacci function (Patrick LeBoutillier)
   5. Re:  Understanding cached fibonnacci function (Thomas Davie)
   6. Re:  Understanding cached fibonnacci function (Daniel Fischer)


----------------------------------------------------------------------

Message: 1
Date: Thu, 29 Jan 2009 16:28:10 +0000
From: "emmanuel.delaborde" <[email protected]>
Subject: Re : Re: [Haskell-beginners] Compile type Error
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"


On 29 Jan 2009, at 16:10, [email protected] wrote:

> Content-Type: text/plain; charset="iso-8859-1"
>
> I didn't compile, but, by the looks of it, I would change
>
> import qualified Data.ByteString as BS (readFile)
>
> for
>
> import qualified Data.ByteString.Lazy as BS (readFile)
>
>
> as it seems sha1 needs a lazy bytestring



Thanks !
It compiles now but brings me to my real problem :)
If I uncomment this line

"md5"  -> md5sum

I get the following :

------

module Main where

import System.Environment (getArgs)
import Data.Digest.OpenSSL.MD5 (md5sum)
import Data.Digest.Pure.SHA (sha1, showDigest)
import qualified Data.ByteString.Lazy as BS (readFile)

-- sha1 :: ByteString -> Digest
-- readFile :: FilePath -> IO ByteString
-- md5sum :: ByteString -> String
-- showDigest :: Digest -> String

checkHash :: String -> String -> String -> IO ()
checkHash codec hash file =
   let f = case codec of
             "md5"  -> md5sum
             "sha1" -> showDigest . sha1
             _      -> error "Codec must be md5 or sha1 !" in
   BS.readFile file >>= \fileBS ->
   let fileHash = f fileBS in
   print (hash == fileHash)

main =
   getArgs >>= \as ->
   case as of
     (codec:hash:file:_) -> checkHash codec hash file
     _                    -> usage

usage = print "checksum codec hash file"

------

which now fails to compile with this error  :

checksum.hs:17:22:
     Couldn't match expected type `Data.ByteString.Internal.ByteString'
            against inferred type  
`Data.ByteString.Lazy.Internal.ByteString'
     In the expression: showDigest . sha1
     In a case alternative: "sha1" -> showDigest . sha1
     In the expression:
         case codec of {
           "md5" -> md5sum
           "sha1" -> showDigest . sha1
           _ -> error "Codec must be md5 or sha1 !" }


How can I both use md5sum and sha1 when one use a lazy ByteString end  
the other one does not ?

Thanks

E





--
Emmanuel Delaborde
Web Technologist
Cimex
53-55 Scrutton Street, London UK, EC2A 4PJ
T: +44 (0)20 7324 7780
F: +44 (0)20 7324 7781
http://www.cimex.com


-----------------------------------------------------------------------------------------------

This e-mail (and any attachments) is confidential and may contain 
personal views which are not the views of Cimex Media Ltd and 
any affiliated companies, unless specifically stated. It is intended 
for the use of the individual or group to whom it is addressed. If 
you have received it in error, please delete it from your system, 
do not use, copy or disclose the information in any way nor act in 
reliance on it and please notify [email protected]

A company registered in England  Wales. Company Number 03765711
Registered Office : The Olde Bakehouse, 156 Watling Street East, Towcester,
Northants NN12 6DB

This email was scanned by Postini, the leading provider in Managed Email 
Security.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090129/e7355d2e/attachment-0001.htm

------------------------------

Message: 2
Date: Thu, 29 Jan 2009 17:41:06 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Compile type Error
To: "emmanuel.delaborde" <[email protected]>,
        [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="iso-8859-1"

Am Donnerstag, 29. Januar 2009 16:25 schrieb emmanuel.delaborde:
> Hello
>
> I have the following snippet :
>
> ----------------------------------------------------------
>
> module Main where
>
> import System.Environment (getArgs)
> import Data.Digest.OpenSSL.MD5 (md5sum)
> import Data.Digest.Pure.SHA (sha1, showDigest)
> import qualified Data.ByteString as BS (readFile)
>
> -- sha1 :: ByteString -> Digest
> -- readFile :: FilePath -> IO ByteString
> -- md5sum :: ByteString -> String
> -- showDigest :: Digest -> String
>
> checkHash :: String -> String -> String -> IO ()
> checkHash codec hash file =
>    let f = case codec of
>              --"md5"  -> md5sum
>              "sha1" -> showDigest . sha1
>              _      -> error "Codec must be md5 or sha1 !" in
>    BS.readFile file >>= \fileBS ->
>    let fileHash = f fileBS in
>    print (hash == fileHash)
>
> main =
>    getArgs >>= \as ->
>    case as of
>      (codec:hash:file:_) -> checkHash codec hash file
>      _                    -> usage
>
> usage = print "checksum codec hash file"
>
> ----------------------------------------------------------
>
> which fails to compile, this is the error I get :
>
>
> checksum.hs:20:19:
>      Couldn't match expected type
> `Data.ByteString.Lazy.Internal.ByteString'
>             against inferred type `Data.ByteString.Internal.ByteString'
>      In the first argument of `f', namely `fileBS'
>      In the expression: f fileBS
>      In the definition of `fileHash': fileHash = f fileBS
>
>
>
>
> it looks like  (showDigest . sha1) expects
> Data.ByteString.Lazy.Internal.ByteString but gets
> Data.ByteString.Internal.ByteString
>
> What can I do ?

import qualified Data.ByteString.Lazy as BS (readFile)

should do it.

>
> Thanks
>
> E.

Cheers,
Daniel



------------------------------

Message: 3
Date: Thu, 29 Jan 2009 19:33:21 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Compile type Error
To: "emmanuel.delaborde" <[email protected]>,
        [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="iso-8859-1"

Am Donnerstag, 29. Januar 2009 17:28 schrieb emmanuel.delaborde:
> On 29 Jan 2009, at 16:10, [email protected] wrote:
> > Content-Type: text/plain; charset="iso-8859-1"
> >
> > I didn't compile, but, by the looks of it, I would change
> >
> > import qualified Data.ByteString as BS (readFile)
> >
> > for
> >
> > import qualified Data.ByteString.Lazy as BS (readFile)
> >
> >
> > as it seems sha1 needs a lazy bytestring
>
> Thanks !
> It compiles now but brings me to my real problem :)
> If I uncomment this line
>
> "md5"  -> md5sum
>
> I get the following :
>
> ------
>
> module Main where
>
> import System.Environment (getArgs)
> import Data.Digest.OpenSSL.MD5 (md5sum)
> import Data.Digest.Pure.SHA (sha1, showDigest)
> import qualified Data.ByteString.Lazy as BS (readFile)
>
> -- sha1 :: ByteString -> Digest
> -- readFile :: FilePath -> IO ByteString
> -- md5sum :: ByteString -> String
> -- showDigest :: Digest -> String
>
> checkHash :: String -> String -> String -> IO ()
> checkHash codec hash file =
>    let f = case codec of
>              "md5"  -> md5sum
>              "sha1" -> showDigest . sha1
>              _      -> error "Codec must be md5 or sha1 !" in
>    BS.readFile file >>= \fileBS ->
>    let fileHash = f fileBS in
>    print (hash == fileHash)
>
> main =
>    getArgs >>= \as ->
>    case as of
>      (codec:hash:file:_) -> checkHash codec hash file
>      _                    -> usage
>
> usage = print "checksum codec hash file"
>
> ------
>
> which now fails to compile with this error  :
>
> checksum.hs:17:22:
>      Couldn't match expected type `Data.ByteString.Internal.ByteString'
>             against inferred type
> `Data.ByteString.Lazy.Internal.ByteString'
>      In the expression: showDigest . sha1
>      In a case alternative: "sha1" -> showDigest . sha1
>      In the expression:
>          case codec of {
>            "md5" -> md5sum
>            "sha1" -> showDigest . sha1
>            _ -> error "Codec must be md5 or sha1 !" }
>
>
> How can I both use md5sum and sha1 when one use a lazy ByteString end
> the other one does not ?

Convert lazy to strict ByteStrings before using md5sum

import qualified Data.ByteString as S    -- strict ByteStrings
import qualified Data.ByteString.Lazy as L

checkHash :: String -> String -> String -> IO ()
checkHash codec hash file =
   let f = case codec of
             "md5"  -> md5sum . S.concat . L.toChunks
             "sha1" -> showDigest . sha1
             _      -> error "Codec must be md5 or sha1 !" in
   L.readFile file >>= \fileBS ->
   let fileHash = f fileBS in
   print (hash == fileHash)

or the other way round:

checkHash :: String -> String -> String -> IO ()
checkHash codec hash file =
   let f = case codec of
             "md5"  -> md5sum
             "sha1" -> showDigest . sha1 . L.fromChunks . (:[])
             _      -> error "Codec must be md5 or sha1 !" in
   S.readFile file >>= \fileBS ->
   let fileHash = f fileBS in
   print (hash == fileHash)



>
> Thanks
>
> E

Cheers,
Daniel



------------------------------

Message: 4
Date: Thu, 29 Jan 2009 13:46:18 -0500
From: Patrick LeBoutillier <[email protected]>
Subject: [Haskell-beginners] Understanding cached fibonnacci function
To: beginners <[email protected]>
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

Hi all,

I recently stumbled on this example in some wiki:

mfib :: Int -> Integer
mfib = (map fib [0 ..] !!)
  where fib 0 = 0
        fib 1 = 1
        fib n = mfib (n-2) + mfib (n-1)

I don't understand how the results get cached. When mfib is
recursively called, doesn't a new (map fib [0 ..] !!) start over
again? Or perhaps I'm thinking too imperatively here...

Also, if I change the definition to this (adding "a" on both sides):

mfib :: Int -> Integer
mfib a = (map fib [0 ..] !!) a
  where fib 0 = 0
        fib 1 = 1
        fib n = mfib (n-2) + mfib (n-1)

the funtion becomes slow again. Why is that?


Thanks a lot,

Patrick LeBoutillier



-- 
=====================
Patrick LeBoutillier
Rosemère, Québec, Canada


------------------------------

Message: 5
Date: Thu, 29 Jan 2009 20:29:35 +0100
From: Thomas Davie <[email protected]>
Subject: Re: [Haskell-beginners] Understanding cached fibonnacci
        function
To: Patrick LeBoutillier <[email protected]>
Cc: beginners <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes


On 29 Jan 2009, at 19:46, Patrick LeBoutillier wrote:

> Hi all,
>
> I recently stumbled on this example in some wiki:
>
> mfib :: Int -> Integer
> mfib = (map fib [0 ..] !!)
>  where fib 0 = 0
>        fib 1 = 1
>        fib n = mfib (n-2) + mfib (n-1)
>
> I don't understand how the results get cached. When mfib is
> recursively called, doesn't a new (map fib [0 ..] !!) start over
> again? Or perhaps I'm thinking too imperatively here...
>
> Also, if I change the definition to this (adding "a" on both sides):
>
> mfib :: Int -> Integer
> mfib a = (map fib [0 ..] !!) a
>  where fib 0 = 0
>        fib 1 = 1
>        fib n = mfib (n-2) + mfib (n-1)
>
> the funtion becomes slow again. Why is that?

The reason that the second one is slower is that ghc makes a  
distinction that so called CAFs (constant applicative forms) are  
likely to be constants, and evaluates them once.  Thus, your list (map  
fib [0..]) gets kept between runs.  In the second form though, ghc  
sees a function, and evaluates it every time it gets called, which  
makes it into an exponential time algorithm.

An aside:  fibs !! 0 is usually defined to be 1.

Here's another couple of definitions of fib for you to play with, and  
try and figure out the properties of:
mfib :: Int -> Integer
mfib = ((fibs  1 1) !!)

fibs :: Integer -> Integer -> [Integer]
fibs n m = n : fibs m (n+m)

-- and
fibs :: [Integer]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)

Have fun

Bob



------------------------------

Message: 6
Date: Thu, 29 Jan 2009 21:22:44 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Understanding cached fibonnacci
        function
To: Thomas Davie <[email protected]>, Patrick LeBoutillier
        <[email protected]>
Cc: beginners <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="iso-8859-1"

Am Donnerstag, 29. Januar 2009 20:29 schrieb Thomas Davie:
>
> The reason that the second one is slower is that ghc makes a
> distinction that so called CAFs (constant applicative forms) are
> likely to be constants, and evaluates them once.  Thus, your list (map
> fib [0..]) gets kept between runs.  In the second form though, ghc
> sees a function, and evaluates it every time it gets called, which
> makes it into an exponential time algorithm.

However, if you compile it with -O2, the optimiser sees it's better to keep 
the list and it's again a linear time algorithm.

>
> An aside:  fibs !! 0 is usually defined to be 1.

I meet fibs !! 0 == 0 more often.

>
> Here's another couple of definitions of fib for you to play with, and
> try and figure out the properties of:
> mfib :: Int -> Integer
> mfib = ((fibs  1 1) !!)
>
> fibs :: Integer -> Integer -> [Integer]
> fibs n m = n : fibs m (n+m)
>
> -- and
> fibs :: [Integer]
> fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
>
> Have fun

Not to forget the marvellous

import Control.Monad.Fix

fibs :: [Integer]
fibs = fix ((0:) . scanl (+) 1)

>
> Bob



------------------------------

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 7, Issue 26
****************************************

Reply via email to