Opaque (to me) compilation error

In the following code: prefix_md5 :: String -> Data.ByteString.ByteString prefix_md5 filename = do let prefix_length = 1024 file <- System.IO.openBinaryFile filename System.IO.ReadMode :: (IO System.IO.Handle) data_read <- Data.ByteString.hGet file prefix_length :: (IO Data.ByteString.ByteString) _ <- System.IO.hClose file let hasher = Crypto.Hash.MD5.init :: Crypto.Hash.MD5.Ctx let hasher2 = Crypto.Hash.MD5.update hasher data_read :: Crypto.Hash.MD5.Ctx let digest = Crypto.Hash.MD5.finalize hasher2 :: Data.ByteString.ByteString return digest :: (IO Data.ByteString.ByteString) I get the error: Md5s.hs:13:5: Couldn't match type `IO Data.ByteString.ByteString' with `Data.ByteString.ByteString' Expected type: IO System.IO.Handle -> (System.IO.Handle -> IO Data.ByteString.ByteString) -> Data.ByteString.ByteString Actual type: IO System.IO.Handle -> (System.IO.Handle -> IO Data.ByteString.ByteString) -> IO Data.ByteString.ByteString In a stmt of a 'do' block: file <- System.IO.openBinaryFile filename System.IO.ReadMode :: IO System.IO.Handle How should I interpret that error to solve this kind of problem on my own in the future? I don't see where the line in question does anything with ByteString's! How might I correct this function to eliminate the error? Thanks! -- Dan Stromberg

You're missing IO in the type declaration, which I believe means that do
block is running in the Id monad -- by inference, Id ByteString.
On Fri, Nov 13, 2015 at 8:41 PM, Dan Stromberg
In the following code: prefix_md5 :: String -> Data.ByteString.ByteString prefix_md5 filename = do let prefix_length = 1024 file <- System.IO.openBinaryFile filename System.IO.ReadMode :: (IO System.IO.Handle) data_read <- Data.ByteString.hGet file prefix_length :: (IO Data.ByteString.ByteString) _ <- System.IO.hClose file let hasher = Crypto.Hash.MD5.init :: Crypto.Hash.MD5.Ctx let hasher2 = Crypto.Hash.MD5.update hasher data_read :: Crypto.Hash.MD5.Ctx let digest = Crypto.Hash.MD5.finalize hasher2 :: Data.ByteString.ByteString return digest :: (IO Data.ByteString.ByteString)
I get the error: Md5s.hs:13:5: Couldn't match type `IO Data.ByteString.ByteString' with `Data.ByteString.ByteString' Expected type: IO System.IO.Handle -> (System.IO.Handle -> IO Data.ByteString.ByteString) -> Data.ByteString.ByteString Actual type: IO System.IO.Handle -> (System.IO.Handle -> IO Data.ByteString.ByteString) -> IO Data.ByteString.ByteString In a stmt of a 'do' block: file <- System.IO.openBinaryFile filename System.IO.ReadMode :: IO System.IO.Handle
How should I interpret that error to solve this kind of problem on my own in the future? I don't see where the line in question does anything with ByteString's!
How might I correct this function to eliminate the error?
Thanks!
-- Dan Stromberg
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

Note that the analysis in my previous message is based on a trick I saw a
year ago and clearly don't properly remember or understand, because there
is no "Id" monad and the *Identity* monad is apparently not in base (though
you might still have it there, it's in both mtl and transformers).
But the bit about your type signature still stands. I'm quite certain of
that part. :)
On Fri, Nov 13, 2015 at 9:24 PM, Theodore Lief Gannon
You're missing IO in the type declaration, which I believe means that do block is running in the Id monad -- by inference, Id ByteString.
On Fri, Nov 13, 2015 at 8:41 PM, Dan Stromberg
wrote: In the following code: prefix_md5 :: String -> Data.ByteString.ByteString prefix_md5 filename = do let prefix_length = 1024 file <- System.IO.openBinaryFile filename System.IO.ReadMode :: (IO System.IO.Handle) data_read <- Data.ByteString.hGet file prefix_length :: (IO Data.ByteString.ByteString) _ <- System.IO.hClose file let hasher = Crypto.Hash.MD5.init :: Crypto.Hash.MD5.Ctx let hasher2 = Crypto.Hash.MD5.update hasher data_read :: Crypto.Hash.MD5.Ctx let digest = Crypto.Hash.MD5.finalize hasher2 :: Data.ByteString.ByteString return digest :: (IO Data.ByteString.ByteString)
I get the error: Md5s.hs:13:5: Couldn't match type `IO Data.ByteString.ByteString' with `Data.ByteString.ByteString' Expected type: IO System.IO.Handle -> (System.IO.Handle -> IO Data.ByteString.ByteString) -> Data.ByteString.ByteString Actual type: IO System.IO.Handle -> (System.IO.Handle -> IO Data.ByteString.ByteString) -> IO Data.ByteString.ByteString In a stmt of a 'do' block: file <- System.IO.openBinaryFile filename System.IO.ReadMode :: IO System.IO.Handle
How should I interpret that error to solve this kind of problem on my own in the future? I don't see where the line in question does anything with ByteString's!
How might I correct this function to eliminate the error?
Thanks!
-- Dan Stromberg
_______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

On Sat, Nov 14, 2015 at 9:24 AM, Theodore Lief Gannon
You're missing IO in the type declaration, which I believe means that do block is running in the Id monad -- by inference, Id ByteString.
There's no running in the Id monad. The compiler doesn't understand monads the way we'd like it to. It's all very syntactic, namely: 1. the compiler desugars the do block into an expression 2. it typechecks the expression: no special understanding of the monad typeclass involved 3. and if there are errors, it reports them What we're seeing is special handling for stage 3: reporting errors in a do-block. Sometimes it helps, sometimes it hinders. For instance, the derivation of this signature is confusing indeed: IO System.IO.Handle -> (System.IO.Handle -> IO Data.ByteString.ByteString) -> Data.ByteString.ByteString -- Kim-Ee

On Sat, Nov 14, 2015 at 10:52 AM, Kim-Ee Yeoh
What we're seeing is special handling for stage 3: reporting errors in a do-block. Sometimes it helps, sometimes it hinders. For instance, the derivation of this signature is confusing indeed:
IO System.IO.Handle -> (System.IO.Handle -> IO Data.ByteString.ByteString) -> Data.ByteString.ByteString
To elaborate, the error message comes from the compiler choking on the monadic bind (>>=) that reveals itself in the desugared code. The (>>=) results from desugaring file <- openBinaryFile filename ReadMode into openBinaryFile filename ReadMode >>= \file -> ... The compiler knows the type signature of (>>=), which wants to see IO Handle -> (Handle -> IO ByteString) -> IO ByteString But the signature of the top-level function insists on IO Handle -> (Handle -> IO ByteString) -> ByteString This is what's the compiler's trying to say. -- Kim-Ee
participants (3)
-
Dan Stromberg
-
Kim-Ee Yeoh
-
Theodore Lief Gannon