Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I putStrLn a Data.ByteString.Internal.ByteString?

I'm learning haskell and decided to try writing some small test programs to get use to Haskell code and using modules. Currently I'm trying to use the first argument to create a password hash using the Cypto.PasswordStore. To test out my program I'm trying to create a hash from the first argument and then print the hash to screen.

import Crypto.PasswordStore
import System.Environment

main = do
    args <- getArgs
    putStrLn (makePassword (head args) 12)

I'm getting the following error:

testmakePassword.hs:8:19:
    Couldn't match expected type `String'
            with actual type `IO Data.ByteString.Internal.ByteString'
    In the return type of a call of `makePassword'
    In the first argument of `putStrLn', namely
      `(makePassword (head args) 12)'
    In a stmt of a 'do' block: putStrLn (makePassword (head args) 12)

I've been using the following links as references but I am now just trial-erroring to no avail. http://hackage.haskell.org/packages/archive/bytestring/0.9.0.4/doc/html/Data-ByteString-Internal.html http://hackage.haskell.org/packages/archive/pwstore-purehaskell/2.1/doc/html/Crypto-PasswordStore.html

like image 355
NerdGGuy Avatar asked Nov 03 '12 01:11

NerdGGuy


2 Answers

You haven't imported ByteString, so it's trying to use the String version of putStrLn. I've provided toBS for the String->ByteString conversion.

Try

import Crypto.PasswordStore
import System.Environment
import qualified Data.ByteString.Char8 as B

toBS = B.pack

main = do
    args <- getArgs
    makePassword (toBS (head args)) 12 >>= B.putStrLn
like image 87
AndrewC Avatar answered Nov 19 '22 09:11

AndrewC


You have to do two things differently. First, makePassword is in IO, so you need to bind the result to a name and then pass the name to the IO function. Secondly, you need to import IO functions from Data.ByteString

import Crypto.PasswordStore
import System.Environment
import qualified Data.ByteString as B

main = do
    args <- getArgs
    pwd <- makePassword (B.pack $ head args) 12
    B.putStrLn pwd

Or, if you won't be using the password result anywhere else, you can use bind to connect the two functions directly:

main = do
    args <- getArgs
    B.putStrLn =<< makePassword (B.pack $ head args) 12
like image 39
John L Avatar answered Nov 19 '22 09:11

John L