<div dir="ltr"><br clear="all"><div>I'm continuing my now-and-then exploration of Haskell.</div><div><br></div><div>I'm getting a new crop of type errors that I'm pulling my hair out over.</div><div><br></div><div>The errors I'm getting are:</div><div><br></div><div><div>$ make</div><div>below cmd output started 2015 Tue Dec 01 04:05:17 PM PST</div><div># --make will go out and find what to build</div><div>ghc -Wall --make -o dph dph.hs Split0.hs</div><div>[1 of 3] Compiling Split0 ( Split0.hs, Split0.o )</div><div>[2 of 3] Compiling Md5s ( Md5s.hs, Md5s.o )</div><div>[3 of 3] Compiling Main ( dph.hs, dph.o )</div><div><br></div><div>dph.hs:13:13:</div><div> Couldn't match type `IO' with `(,) (IO String)'</div><div> Expected type: (IO String, String)</div><div> Actual type: IO String</div><div> In a stmt of a 'do' block: hash <- prefix_md5 filename :: IO String</div><div> In the expression:</div><div> do { hash <- prefix_md5 filename :: IO String;</div><div> (hash, filename) }</div><div> In an equation for `do_prefix_hash':</div><div> do_prefix_hash filename</div><div> = do { hash <- prefix_md5 filename :: IO String;</div><div> (hash, filename) }</div><div><br></div><div>dph.hs:14:6:</div><div> Couldn't match type `[Char]' with `IO String'</div><div> Expected type: IO String</div><div> Actual type: String</div><div> In the expression: hash</div><div> In a stmt of a 'do' block: (hash, filename)</div><div> In the expression:</div><div> do { hash <- prefix_md5 filename :: IO String;</div><div> (hash, filename) }</div><div><br></div><div>dph.hs:24:23:</div><div> Couldn't match type `[]' with `IO'</div><div> Expected type: IO (IO String, String)</div><div> Actual type: [(IO String, String)]</div><div> In a stmt of a 'do' block:</div><div> io_hash_tuples <- map do_prefix_hash filenames ::</div><div> [(IO String, String)]</div><div> In the expression:</div><div> do { buffer <- (hGetContents stdin) :: IO String;</div><div> let filenames = ...;</div><div> io_hash_tuples <- map do_prefix_hash filenames ::</div><div> [(IO String, String)];</div><div> hash_tuples <- sequence io_hash_tuples :: [(String, String)];</div><div> .... }</div><div> In an equation for `main':</div><div> main</div><div> = do { buffer <- (hGetContents stdin) :: IO String;</div><div> let filenames = ...;</div><div> io_hash_tuples <- map do_prefix_hash filenames ::</div><div> [(IO String, String)];</div><div> .... }</div><div><br></div><div>dph.hs:25:20:</div><div> Couldn't match type `[a0]' with `(String, String)'</div><div> Expected type: [(String, String)]</div><div> Actual type: [[a0]]</div><div> In the return type of a call of `sequence'</div><div> In a stmt of a 'do' block:</div><div> hash_tuples <- sequence io_hash_tuples :: [(String, String)]</div><div> In the expression:</div><div> do { buffer <- (hGetContents stdin) :: IO String;</div><div> let filenames = ...;</div><div> io_hash_tuples <- map do_prefix_hash filenames ::</div><div> [(IO String, String)];</div><div> hash_tuples <- sequence io_hash_tuples :: [(String, String)];</div><div> .... }</div><div><br></div><div>dph.hs:25:20:</div><div> Couldn't match type `[]' with `IO'</div><div> Expected type: IO (String, String)</div><div> Actual type: [(String, String)]</div><div> In a stmt of a 'do' block:</div><div> hash_tuples <- sequence io_hash_tuples :: [(String, String)]</div><div> In the expression:</div><div> do { buffer <- (hGetContents stdin) :: IO String;</div><div> let filenames = ...;</div><div> io_hash_tuples <- map do_prefix_hash filenames ::</div><div> [(IO String, String)];</div><div> hash_tuples <- sequence io_hash_tuples :: [(String, String)];</div><div> .... }</div><div> In an equation for `main':</div><div> main</div><div> = do { buffer <- (hGetContents stdin) :: IO String;</div><div> let filenames = ...;</div><div> io_hash_tuples <- map do_prefix_hash filenames ::</div><div> [(IO String, String)];</div><div> .... }</div><div><br></div><div>dph.hs:25:29:</div><div> Couldn't match expected type `[[a0]]'</div><div> with actual type `(IO String, String)'</div><div> In the first argument of `sequence', namely `io_hash_tuples'</div><div> In a stmt of a 'do' block:</div><div> hash_tuples <- sequence io_hash_tuples :: [(String, String)]</div><div> In the expression:</div><div> do { buffer <- (hGetContents stdin) :: IO String;</div><div> let filenames = ...;</div><div> io_hash_tuples <- map do_prefix_hash filenames ::</div><div> [(IO String, String)];</div><div> hash_tuples <- sequence io_hash_tuples :: [(String, String)];</div><div> .... }</div><div><br></div><div>dph.hs:26:39:</div><div> Couldn't match expected type `[(String, String)]'</div><div> with actual type `(String, String)'</div><div> In the second argument of `map', namely `hash_tuples'</div><div> In the expression: map tuple_to_string hash_tuples :: [String]</div><div> In an equation for `strings':</div><div> strings = map tuple_to_string hash_tuples :: [String]</div><div>make: *** [dph] Error 1</div><div>above cmd output done 2015 Tue Dec 01 04:05:18 PM PST</div></div><div><br></div><div><br></div><div>dph.hs looks like:</div><div><div>import Md5s</div><div>import Split0</div><div>import System.IO</div><div><br></div><div>get_filenames :: String -> [String]</div><div>get_filenames buffer = do</div><div> -- Let's hope this doesn't give locale-related roundtrip problems.</div><div> Split0.split0 '\0' buffer :: [String]</div><div><br></div><div>do_prefix_hash :: String -> (IO String, String)</div><div>do_prefix_hash filename = do</div><div> hash <- Md5s.prefix_md5 filename :: (IO String)</div><div> (hash, filename)</div><div><br></div><div>tuple_to_string :: (String, String) -> String</div><div>tuple_to_string (first, second) = do</div><div> (show first) ++ " " ++ (show second)</div><div><br></div><div>main :: IO ()</div><div>main = do</div><div> buffer <- (System.IO.hGetContents System.IO.stdin) :: IO String</div><div> let filenames = (get_filenames buffer) :: [String]</div><div> io_hash_tuples <- map do_prefix_hash filenames :: [(IO String, String)]</div><div> hash_tuples <- sequence io_hash_tuples :: [(String, String)]</div><div> let strings = map tuple_to_string hash_tuples :: [String]</div><div> mapM_ putStrLn strings</div></div><div><br></div><div><br></div><div>And Md5s.hs looks like:</div><div><div>module Md5s where</div><div><br></div><div>import qualified System.IO</div><div>import qualified Text.Printf</div><div>-- cabal install cryptohash</div><div>import qualified Crypto.Hash.MD5</div><div>import qualified Data.ByteString</div><div>import qualified Data.ByteString.Lazy</div><div><br></div><div>-- <a href="http://stackoverflow.com/questions/10099921/efficiently-turn-a-bytestring-into-a-hex-representation">http://stackoverflow.com/questions/10099921/efficiently-turn-a-bytestring-into-a-hex-representation</a></div><div>byte_string_to_hex :: Data.ByteString.ByteString -> String</div><div>byte_string_to_hex = concatMap (Text.Printf.printf "%02x") . Data.ByteString.unpack</div><div><br></div><div>prefix_md5 :: String -> IO String</div><div>prefix_md5 filename = do</div><div> let prefix_length = 1024</div><div> file <- System.IO.openBinaryFile filename System.IO.ReadMode :: IO System.IO.Handle</div><div> data_read <- Data.ByteString.hGet file prefix_length :: IO Data.ByteString.ByteString</div><div> _ <- System.IO.hClose file</div><div> let hasher = Crypto.Hash.MD5.init :: Crypto.Hash.MD5.Ctx</div><div> let hasher2 = Crypto.Hash.MD5.update hasher data_read :: Crypto.Hash.MD5.Ctx</div><div> let binary_digest = Crypto.Hash.MD5.finalize hasher2 :: Data.ByteString.ByteString</div><div> let hex_digest = byte_string_to_hex binary_digest :: String</div><div> return hex_digest :: IO String</div><div><br></div><div>full_md5 :: String -> IO String</div><div>full_md5 filename = do</div><div> file <- System.IO.openBinaryFile filename System.IO.ReadMode :: IO System.IO.Handle</div><div> data_read <- Data.ByteString.Lazy.hGetContents file :: IO Data.ByteString.Lazy.ByteString</div><div> let binary_digest = Crypto.Hash.MD5.hashlazy data_read :: Data.ByteString.ByteString</div><div> let hex_digest = byte_string_to_hex binary_digest :: String</div><div> -- Does this get closed for us later?</div><div> -- strace shows the file getting closed without our explicit close.</div><div> -- _ <- System.IO.hClose file</div><div> return hex_digest :: IO String</div></div><div><br></div><div><br></div><div>It might be easier to view these at <a href="http://stromberg.dnsalias.org/svn/equivalence-classes/trunk/equivs3-haskell/">http://stromberg.dnsalias.org/svn/equivalence-classes/trunk/equivs3-haskell/</a> , so the line numbers are precise.</div><div><br></div><div>What is the deal?</div><div><br></div><div>Can anyone tell me what should be running through my head to fix this kind of problem on my own in the future?</div><div><br></div><div>Thanks!</div><div><br></div>-- <br><div class="gmail_signature">Dan Stromberg</div>
</div>