[Haskell-beginners] Compile type Error

Daniel Fischer daniel.is.fischer at web.de
Thu Jan 29 13:33:21 EST 2009


Am Donnerstag, 29. Januar 2009 17:28 schrieb emmanuel.delaborde:
> On 29 Jan 2009, at 16:10, beginners-request at haskell.org 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



More information about the Beginners mailing list