24

Running the following code:

import Crypto.BCrypt
import Data.ByteString.Lazy.Char8

main = do
  maybe_pwhash <- hashPasswordUsingPolicy slowerBcryptHashingPolicy (pack "hunter2")
  print $ maybe_pwhash

I get the following compilation error:

test.hs:5:70:
    Couldn't match expected type `Data.ByteString.Internal.ByteString'
                with actual type `ByteString'
    In the return type of a call of `pack'
    In the second argument of `hashPasswordUsingPolicy', namely
      `(C.pack "hunter2")'
    In a stmt of a 'do' block:
      maybe_pwhash <- hashPasswordUsingPolicy
                        slowerBcryptHashingPolicy (pack "hunter2")

I am confused because I don't see why there is a difference between a Data.ByteString.Internal.ByteString and a ByteString.

hugomg
  • 68,213
  • 24
  • 160
  • 246
  • Answering my own question because I had already written most of it by the time I managed to figure it out... Anyway, I still don't really understand the difference between all the different bytestring types and modules (´Lazy` vs `Strict`, `ByteString.Char8` vs `ByteString`, etc) and the [haskellwiki article](http://www.haskell.org/haskellwiki/Strings) on that seems to be just a stub. Any explanations on that would be much appreciated. – hugomg Dec 22 '13 at 20:49
  • There are two different types of `ByteString`s: lazy and strict. If the module name is not qualified with `Lazy`, then it uses strict `ByteString`. A lazy `ByteString` is essentially a linked list of strict `ByteString`. – user2407038 Dec 23 '13 at 07:55

1 Answers1

10

According to the bcrypt docs, you should be using strict bytestrings

import Data.ByteString.Char8

instead of the lazy ones:

import Data.ByteString.Lazy.Char8
hugomg
  • 68,213
  • 24
  • 160
  • 246
  • 7
    To clarify: There are two kinds of `ByteString`s: Lazy and strict. `Data.ByteString.(Internal.)ByteString` is strict. `Data.ByteString.Lazy.(Internal.)ByteString` is lazy. If you see a plain old unqualified `ByteString` type not matching a qualified `ByteString` type, then it's the other one. – shachaf Dec 22 '13 at 21:54
  • 6
    `.Char8` is evil/broken/experts-only. You shouldn't use it unless you know exactly what it does and what's wrong with it. ByteStrings are byte sequences, not character sequences. With that said, `Data.ByteString.Char8.ByteString` is the same as strict `ByteString` and `Data.ByteString.Lazy.Char8.ByteString` is the same as lazy `ByteString`. There are only two `ByteString`s. – shachaf Dec 22 '13 at 21:58