How to use Data.ByteString ?

Hi, friends the following function works well rollDice n = getStdRandom (randomR (1,n)) :: IO Int now i want to use /dev/random to produce better random number, but it doesnot work rollDice_t n = do hd <- openFile "/dev/random" ReadMode v <- B.hGet hd 1 return (v `mod` n) + 1 No instance for (Integral B.ByteString) arising from a use of `mod' at Money.hs:15:12-20 Possible fix: add an instance declaration for (Integral B.ByteString) In the first argument of `return', namely `(v `mod` n)' In the first argument of `(+)', namely `return (v `mod` n)' In the expression: return (v `mod` n) + 1 then how to use the ByteString properly ? Sincerely!

On May 19, 2009, at 01:07 , z_axis wrote:
rollDice_t n = do hd <- openFile "/dev/random" ReadMode v <- B.hGet hd 1 return (v `mod` n) + 1
No instance for (Integral B.ByteString)
You can't just read a binary string and have it interpreted as a number; you want to use Data.Binary to extract an Int (or whatever) from the ByteString. The same would apply with legacy Strings; in Haskell, String, ByteString, and Int are distinct types and there is no automatic casting. In fact I'm not quite sure why you thought that should work; even Perl would make you unpack(), and C would require you to use an appropriately-aligned buffer and unsafely cast the (char *) to an (int *). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Mon, May 18, 2009 at 10:13 PM, Brandon S. Allbery KF8NH
On May 19, 2009, at 01:07 , z_axis wrote:
rollDice_t n = do hd <- openFile "/dev/random" ReadMode v <- B.hGet hd 1 return (v `mod` n) + 1
No instance for (Integral B.ByteString)
You can't just read a binary string and have it interpreted as a number; you want to use Data.Binary to extract an Int (or whatever) from the ByteString. The same would apply with legacy Strings; in Haskell, String, ByteString, and Int are distinct types and there is no automatic casting. In fact I'm not quite sure why you thought that should work; even Perl would make you unpack(), and C would require you to use an appropriately-aligned buffer and unsafely cast the (char *) to an (int *).
More so, you appear to only be getting one byte from your random number source, so that really limits the range of numbers this function can produce. Also, the error you are getting is more to do with ambigious types because there is a typeclass implied and you didn't add any type annotations yourself. Suggestions: 1) Use Data.ByteString.Lazy 2) Read the file, and don't forget to close it - or rework how you intend to get randoms (a better solution!) 3) Use 'decode' form Data.Binary and add a type signature to get an Int, Word32, or some such. 4) Apply mod and return Thomas

On Mon, May 18, 2009 at 10:13 PM, Brandon S. Allbery KF8NH
On May 19, 2009, at 01:07 , z_axis wrote:
rollDice_t n = do hd <- openFile "/dev/random" ReadMode v <- B.hGet hd 1 return (v `mod` n) + 1
No instance for (Integral B.ByteString)
You can't just read a binary string and have it interpreted as a number; you want to use Data.Binary to extract an Int (or whatever) from the ByteString. The same would apply with legacy Strings; in Haskell, String, ByteString, and Int are distinct types and there is no automatic casting. In fact I'm not quite sure why you thought that should work; even Perl would make you unpack(), and C would require you to use an appropriately-aligned buffer and unsafely cast the (char *) to an (int *).
I just want to add that, this wouldn't stop Visual Basic! I've often seen this bit of scary code in VB: Dim i as Integer = 5 If i = "5" Then ' Do something, because 5 = "5" End If The designers of VB were quite odd though. I frequently find that VB violates the assumptions I make about programming languages (the logical "And" operation isn't short-circuit logic!). Jason

On May 19, 2009, at 01:42 , Jason Dagit wrote:
I've often seen this bit of scary code in VB: Dim i as Integer = 5 If i = "5" Then ' Do something, because 5 = "5" End If
Sure, that works in Perl too. But the equivalent case here would be chr$(5), not "5". -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

On Tue, May 19, 2009 at 8:46 AM, Brandon S. Allbery KF8NH
On May 19, 2009, at 01:42 , Jason Dagit wrote:
I've often seen this bit of scary code in VB: Dim i as Integer = 5 If i = "5" Then ' Do something, because 5 = "5" End If
Sure, that works in Perl too.
That's because in numeric context Perl convert strings into numbers, so even 5 == "5 coffees" would be true... But 5 eq "5 coffees" wouldn't since eq force a string context and 5 is converted to "5" which is not string-equal to "5 coffees". Perl is all about context and is coherent in its weirdness, whereas VB is pretty screwed IIRC. -- Jedaï

On May 19, 2009, at 10:20 , Chaddaï Fouché wrote:
On Tue, May 19, 2009 at 8:46 AM, Brandon S. Allbery KF8NH
wrote: On May 19, 2009, at 01:42 , Jason Dagit wrote:
I've often seen this bit of scary code in VB: Dim i as Integer = 5 If i = "5" Then ' Do something, because 5 = "5" End If
Sure, that works in Perl too.
That's because in numeric context Perl convert strings into numbers, so even 5 == "5 coffees" would be true... But 5 eq "5 coffees" wouldn't since eq force a string context and 5 is converted to "5"
If you use == instead of eq then it will emit a warning and then find them equal. This is something of a common logic error in Perl. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH
participants (5)
-
Brandon S. Allbery KF8NH
-
Chaddaï Fouché
-
Jason Dagit
-
Thomas DuBuisson
-
z_axis