Re: [Haskell-beginners] System.USB.writeInterrupt -- confused by error message from type system

Karol, Alexander,
Thanks for your feedback... I am still a little confused as I shall
explain... first of all let's look at the prototype for 'writeInterrupt',
writeInterrupt :: DeviceHandle -> EndpointAddress -> WriteAction
To me, that reads a "takes a device handle and an endpoint address and
returns a WriteAction", and to quote the WriteAction help text verbatim so
there is no confusion:
type WriteAction = ByteString -> Timeout -> IO (Size, Status)Source
Handy type synonym for write transfers.
"A WriteAction is a function which takes a ByteString to write and
a Timeout.
The function returns an IO action which, when exectued(sic),
returns the number
of bytes that were actually written paired with a Status flag
which indicates whether
the transfer Completed or TimedOut."
Now let's move to my original code and the 'right' code...
action <- writeInterrupt handle endPoint
let action = writeInterrupt handle endPoint
If I understand things correctly up to this point, my mistake was being too
eager in using "<-", my mind at that point was obviously confusing the
return value from WriteAction with the return type of writeInterrupt and I
can see now that what I should have done was use "let" which captures the
WriteAction that is returned which can be executed with the payload and the
timeout on the next line:
(size, status) <- action payload 1000
On this line, the use of "<-" is what is required in order to cause the
promised IO action to perform its duties and return me the tuple of data
sent and status returned from the USB inner workings.
However, we now come to the new type checker error, and this one has me
floored right now. Time and time again I find myself beating my head
against a wall and tearing my hair out trying to understand the
thousand-and-one variations on strings in Haskell! I even tried the
"string-conversions" (convertString) package but decided to battle it out
instead...
First the new code as edited in response to Karol:
testBoard :: Device -> DeviceHandle -> IO ()
testBoard dev handle = do
putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\""
-- write 0x00 0x00 0x00 0x00, get back same...we need to pad
the
-- packet out to 64 bytes for a full-speed device... should
probably
-- get this (64) from the device configuration / description
record
-- for maximum
portability!
let payload = BS.replicate 64 '\0'
let endPoint = EndpointAddress 0 Out
let action = writeInterrupt handle endPoint
(size, status) <- action payload 1000
return ()
And the new error:
usb1.hs:64:28:
Couldn't match expected type
`bytestring-0.9.2.1:Data.ByteString.Internal.ByteString'
with actual type `ByteString'
In the first argument of `action', namely `payload'
In a stmt of a 'do' block: (size, status) <- action payload 1000
In the expression:
do { putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"";
let payload = BS.replicate 64 '\NUL';
let endPoint = EndpointAddress 0 Out;
let action = writeInterrupt handle endPoint;
.... }
Where and why does it think that "Data.ByteString.Internal.ByteString" is
the type of the first parameter to "action" which is quite clearly stated
as being "ByteString" ???
I know that "String", the native type is 4-bytes and that ByteString
(Strict) and ByteString (Lazy) are both 8-bit, which is great, and I
understand that the strict version (at least to me) feels like the
rightmatch to be using for data buffers for a USB transfer but why oh why
oh why can't I understand why the type checker picked up "internal"
somewhere along the way?
In the source code for WriteAction we have this:
type WriteAction = B.ByteString → Timeout → IO (Size, Status)
and at the top of the that source file:
-- from bytestring:
import qualified Data.ByteString as B ( ByteString,
packCStringLen, drop, length )
import qualified Data.ByteString.Internal as BI ( createAndTrim,
createAndTrim' )
import qualified Data.ByteString.Unsafe as BU ( unsafeUseAsCStringLen
)
So why is it trying to be "internal"! I have tried not to be lazy, I have
read everything and looked everywhere before posting again. If it had said:
type WriteAction = BI.ByteString → Timeout → IO (Size, Status)
I would have understood but it doesn't does it ?!
Can somebody explain for me so I can just get on and write my killer USB
application please! LOL
:)
Thanks,
Sean.
On 27 February 2013 12:07, Karol Samborski
Hi Sean,
I think that your function for testing board should look like this:
testBoard :: Device -> DeviceHandle -> IO () testBoard dev handle = do putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"\n" -- write 0x00 0x00 0x00 0x00, get back same... let payload = pack "\x00\x00\x00\x00" let endPoint = EndpointAddress 0 Out let action = writeInterrupt handle endPoint (size, status) <- action payload 1000 return ()
You need to use let because writeInterrupt returns (Timeout -> ByteString -> IO (Size, Bool)) instead of IO (Timeout -> ByteString -> IO (Size, Bool))
Karol
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

You have this line in your code, but that doesn't correlate to the imports
you listed.
BS.replicate 64 '\0'
import qualified Data.ByteString as B ( ByteString,
packCStringLen, drop, length )
import qualified Data.ByteString.Internal as BI ( createAndTrim,
createAndTrim' )
import qualified Data.ByteString.Unsafe as BU ( unsafeUseAsCStringLen
)
So you must have imported Data.ByteString.Lazy as BS somewhere. Change
that to B.replicate and it will probably work.
On Wed, Feb 27, 2013 at 11:41 AM, emacstheviking
Karol, Alexander,
Thanks for your feedback... I am still a little confused as I shall explain... first of all let's look at the prototype for 'writeInterrupt',
writeInterrupt :: DeviceHandle -> EndpointAddress -> WriteAction
To me, that reads a "takes a device handle and an endpoint address and returns a WriteAction", and to quote the WriteAction help text verbatim so there is no confusion:
type WriteAction = ByteString -> Timeout -> IO (Size, Status)Source
Handy type synonym for write transfers.
"A WriteAction is a function which takes a ByteString to write and a Timeout. The function returns an IO action which, when exectued(sic), returns the number of bytes that were actually written paired with a Status flag which indicates whether the transfer Completed or TimedOut."
Now let's move to my original code and the 'right' code...
action <- writeInterrupt handle endPoint let action = writeInterrupt handle endPoint
If I understand things correctly up to this point, my mistake was being too eager in using "<-", my mind at that point was obviously confusing the return value from WriteAction with the return type of writeInterrupt and I can see now that what I should have done was use "let" which captures the WriteAction that is returned which can be executed with the payload and the timeout on the next line:
(size, status) <- action payload 1000
On this line, the use of "<-" is what is required in order to cause the promised IO action to perform its duties and return me the tuple of data sent and status returned from the USB inner workings.
However, we now come to the new type checker error, and this one has me floored right now. Time and time again I find myself beating my head against a wall and tearing my hair out trying to understand the thousand-and-one variations on strings in Haskell! I even tried the "string-conversions" (convertString) package but decided to battle it out instead...
First the new code as edited in response to Karol:
testBoard :: Device -> DeviceHandle -> IO () testBoard dev handle = do
putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"" -- write 0x00 0x00 0x00 0x00, get back same...we need to pad the -- packet out to 64 bytes for a full-speed device... should probably -- get this (64) from the device configuration / description record -- for maximum portability!
let payload = BS.replicate 64 '\0'
let endPoint = EndpointAddress 0 Out let action = writeInterrupt handle endPoint (size, status) <- action payload 1000 return ()
And the new error:
usb1.hs:64:28: Couldn't match expected type `bytestring-0.9.2.1:Data.ByteString.Internal.ByteString' with actual type `ByteString' In the first argument of `action', namely `payload' In a stmt of a 'do' block: (size, status) <- action payload 1000
In the expression: do { putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\""; let payload = BS.replicate 64 '\NUL'; let endPoint = EndpointAddress 0 Out; let action = writeInterrupt handle endPoint; .... }
Where and why does it think that "Data.ByteString.Internal.ByteString" is the type of the first parameter to "action" which is quite clearly stated as being "ByteString" ??? I know that "String", the native type is 4-bytes and that ByteString (Strict) and ByteString (Lazy) are both 8-bit, which is great, and I understand that the strict version (at least to me) feels like the rightmatch to be using for data buffers for a USB transfer but why oh why oh why can't I understand why the type checker picked up "internal" somewhere along the way?
In the source code for WriteAction we have this:
type WriteAction = B.ByteString → Timeout → IO (Size, Status)
and at the top of the that source file:
-- from bytestring: import qualified Data.ByteString as B ( ByteString, packCStringLen, drop, length ) import qualified Data.ByteString.Internal as BI ( createAndTrim, createAndTrim' ) import qualified Data.ByteString.Unsafe as BU ( unsafeUseAsCStringLen )
So why is it trying to be "internal"! I have tried not to be lazy, I have read everything and looked everywhere before posting again. If it had said:
type WriteAction = BI.ByteString → Timeout → IO (Size, Status)
I would have understood but it doesn't does it ?! Can somebody explain for me so I can just get on and write my killer USB application please! LOL
:) Thanks, Sean.
On 27 February 2013 12:07, Karol Samborski
wrote: Hi Sean,
I think that your function for testing board should look like this:
testBoard :: Device -> DeviceHandle -> IO () testBoard dev handle = do putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"\n" -- write 0x00 0x00 0x00 0x00, get back same... let payload = pack "\x00\x00\x00\x00" let endPoint = EndpointAddress 0 Out let action = writeInterrupt handle endPoint (size, status) <- action payload 1000 return ()
You need to use let because writeInterrupt returns (Timeout -> ByteString -> IO (Size, Bool)) instead of IO (Timeout -> ByteString -> IO (Size, Bool))
Karol
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

From digging around it seems that I might have in fact got a broken set of
David, maybe my code got chopped then because this is the start of my
program:
module Main where
import Data.ByteString.Char8 as BS hiding (putStrLn) ***HERE IT IS***
import Data.String.Conversions as SC
import Data.Word (Word16)
import Data.Vector as V (filterM, null, (!)) --as V hiding ((++))
import System.USB
import System.Environment
where the "BS" (pardon the pun) is quite plainly defined. And changing it
as suggested only yields this:
usb1.hs:61:18:
Not in scope: `B.replicate'
Perhaps you meant `BS.replicate' (imported from Data.ByteString.Char8)
So I don't think that's the solution.
libraries. I found this:
http://stackoverflow.com/questions/12576817/couldnt-match-expected-type-with...
and
when I actually listed the bytestring packages as suggested I get this
(terrible!) output:
WARNING: there are broken packages. Run 'ghc-pkg check' for more
details.
/var/lib/ghc/package.conf.d
bytestring-0.9.2.1
/home/sean/.ghc/i386-linux-7.4.2/package.conf.d
bytestring-0.10.0.1
and doing the suggested "ghc-pkg check" made me reach for the toilet
rolls....
WARNING: there are broken packages. Run 'ghc-pkg check' for more details.
/var/lib/ghc/package.conf.d
bytestring-0.9.2.1
/home/sean/.ghc/i386-linux-7.4.2/package.conf.d
bytestring-0.10.0.1
sean@sean-Dimension-4700 ~/Documents/haskell/usb $ ghc-pkg check
There are problems in package snap-core-0.9.3.1:
dependency "vector-0.10.0.1-fdf8e0c3f3c1cae1113ab97c34aa5c14" doesn't
exist
There are problems in package tls-extra-0.6.1:
dependency "vector-0.10.0.1-fdf8e0c3f3c1cae1113ab97c34aa5c14" doesn't
exist
There are problems in package crypto-numbers-0.1.3:
dependency "vector-0.10.0.1-fdf8e0c3f3c1cae1113ab97c34aa5c14" doesn't
exist
There are problems in package repa-io-3.2.2.201204.1:
dependency "vector-0.10.0.1-fdf8e0c3f3c1cae1113ab97c34aa5c14" doesn't
exist
There are problems in package repa-algorithms-3.2.2.201204.1:
dependency "vector-0.10.0.1-fdf8e0c3f3c1cae1113ab97c34aa5c14" doesn't
exist
There are problems in package repa-3.2.2.201204.1:
dependency "vector-0.10.0.1-fdf8e0c3f3c1cae1113ab97c34aa5c14" doesn't
exist
There are problems in package vty-4.7.0.20:
dependency "vector-0.10.0.1-fdf8e0c3f3c1cae1113ab97c34aa5c14" doesn't
exist
There are problems in package pango-0.12.2:
dependency "cairo-0.12.3-89ddba0b76b80ddab58fabdf2a845c76" doesn't exist
There are problems in package webkit-0.12.3:
dependency "cairo-0.12.3-89ddba0b76b80ddab58fabdf2a845c76" doesn't exist
There are problems in package gtk-0.12.3:
dependency "cairo-0.12.3-89ddba0b76b80ddab58fabdf2a845c76" doesn't exist
The following packages are broken, either because they have a problem
listed above, or because they depend on a broken package.
snap-core-0.9.3.1
tls-extra-0.6.1
crypto-numbers-0.1.3
repa-io-3.2.2.201204.1
repa-algorithms-3.2.2.201204.1
repa-3.2.2.201204.1
vty-4.7.0.20
pango-0.12.2
webkit-0.12.3
gtk-0.12.3
hakyll-4.1.4.0
snap-server-0.9.3.1
http-conduit-1.8.7.1
tls-1.1.2
crypto-pubkey-0.1.2
gloss-raster-1.7.7.201204.1
yi-0.6.6.0
hbro-0.9.0.0
hbro-contrib-0.9.0.0
ltk-0.12.0.0
So... I think that my real problem is that I have a badly broken package
setup. I am going to remove both bytestring packages as well as all those
broken things (I don't need them anyway( and reinstall and see what
happens. I hope it just goes away.... I really want to be USB programming
not fixing up my installation.. nothing like computers to make life awkward.
Thanks.
Sean.
On 27 February 2013 19:21, David McBride
You have this line in your code, but that doesn't correlate to the imports you listed.
BS.replicate 64 '\0'
import qualified Data.ByteString as B ( ByteString, packCStringLen, drop, length ) import qualified Data.ByteString.Internal as BI ( createAndTrim, createAndTrim' ) import qualified Data.ByteString.Unsafe as BU ( unsafeUseAsCStringLen )
So you must have imported Data.ByteString.Lazy as BS somewhere. Change that to B.replicate and it will probably work.
On Wed, Feb 27, 2013 at 11:41 AM, emacstheviking
wrote: Karol, Alexander,
Thanks for your feedback... I am still a little confused as I shall explain... first of all let's look at the prototype for 'writeInterrupt',
writeInterrupt :: DeviceHandle -> EndpointAddress -> WriteAction
To me, that reads a "takes a device handle and an endpoint address and returns a WriteAction", and to quote the WriteAction help text verbatim so there is no confusion:
type WriteAction = ByteString -> Timeout -> IO (Size, Status)Source
Handy type synonym for write transfers.
"A WriteAction is a function which takes a ByteString to write and a Timeout. The function returns an IO action which, when exectued(sic), returns the number of bytes that were actually written paired with a Status flag which indicates whether the transfer Completed or TimedOut."
Now let's move to my original code and the 'right' code...
action <- writeInterrupt handle endPoint let action = writeInterrupt handle endPoint
If I understand things correctly up to this point, my mistake was being too eager in using "<-", my mind at that point was obviously confusing the return value from WriteAction with the return type of writeInterrupt and I can see now that what I should have done was use "let" which captures the WriteAction that is returned which can be executed with the payload and the timeout on the next line:
(size, status) <- action payload 1000
On this line, the use of "<-" is what is required in order to cause the promised IO action to perform its duties and return me the tuple of data sent and status returned from the USB inner workings.
However, we now come to the new type checker error, and this one has me floored right now. Time and time again I find myself beating my head against a wall and tearing my hair out trying to understand the thousand-and-one variations on strings in Haskell! I even tried the "string-conversions" (convertString) package but decided to battle it out instead...
First the new code as edited in response to Karol:
testBoard :: Device -> DeviceHandle -> IO () testBoard dev handle = do
putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"" -- write 0x00 0x00 0x00 0x00, get back same...we need to pad the -- packet out to 64 bytes for a full-speed device... should probably -- get this (64) from the device configuration / description record -- for maximum portability!
let payload = BS.replicate 64 '\0'
let endPoint = EndpointAddress 0 Out let action = writeInterrupt handle endPoint (size, status) <- action payload 1000 return ()
And the new error:
usb1.hs:64:28: Couldn't match expected type `bytestring-0.9.2.1:Data.ByteString.Internal.ByteString' with actual type `ByteString' In the first argument of `action', namely `payload' In a stmt of a 'do' block: (size, status) <- action payload 1000
In the expression: do { putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\""; let payload = BS.replicate 64 '\NUL'; let endPoint = EndpointAddress 0 Out; let action = writeInterrupt handle endPoint; .... }
Where and why does it think that "Data.ByteString.Internal.ByteString" is the type of the first parameter to "action" which is quite clearly stated as being "ByteString" ??? I know that "String", the native type is 4-bytes and that ByteString (Strict) and ByteString (Lazy) are both 8-bit, which is great, and I understand that the strict version (at least to me) feels like the rightmatch to be using for data buffers for a USB transfer but why oh why oh why can't I understand why the type checker picked up "internal" somewhere along the way?
In the source code for WriteAction we have this:
type WriteAction = B.ByteString → Timeout → IO (Size, Status)
and at the top of the that source file:
-- from bytestring: import qualified Data.ByteString as B ( ByteString, packCStringLen, drop, length ) import qualified Data.ByteString.Internal as BI ( createAndTrim, createAndTrim' ) import qualified Data.ByteString.Unsafe as BU ( unsafeUseAsCStringLen )
So why is it trying to be "internal"! I have tried not to be lazy, I have read everything and looked everywhere before posting again. If it had said:
type WriteAction = BI.ByteString → Timeout → IO (Size, Status)
I would have understood but it doesn't does it ?! Can somebody explain for me so I can just get on and write my killer USB application please! LOL
:) Thanks, Sean.
On 27 February 2013 12:07, Karol Samborski
wrote: Hi Sean,
I think that your function for testing board should look like this:
testBoard :: Device -> DeviceHandle -> IO () testBoard dev handle = do putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"\n" -- write 0x00 0x00 0x00 0x00, get back same... let payload = pack "\x00\x00\x00\x00" let endPoint = EndpointAddress 0 Out let action = writeInterrupt handle endPoint (size, status) <- action payload 1000 return ()
You need to use let because writeInterrupt returns (Timeout -> ByteString -> IO (Size, Bool)) instead of IO (Timeout -> ByteString -> IO (Size, Bool))
Karol
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

HURRAH! I have finally got it to compile...
I manually deleted the broken packages (I play too much anyway so a tidy up
was in order) and it still failed with:
[1 of 1] Compiling Main ( usb1.hs, usb1.o )
usb1.hs:64:28:
Couldn't match expected type
`bytestring-0.9.2.1:Data.ByteString.Internal.ByteString'
with actual type `ByteString'
In the first argument of `action', namely `payload'
In a stmt of a 'do' block: (size, status) <- action payload 1000
In the expression:
do { putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"";
let payload = BS.replicate 64 '\NUL';
let endPoint = EndpointAddress 0 Out;
let action = writeInterrupt handle endPoint;
.... }
And I suddenly remembered that despite the clean up I still had two
bytestring packages:
sean@sean-Dimension-4700 ~/Documents/haskell/usb $ ghc-pkg list bytestring
/var/lib/ghc/package.conf.d
bytestring-0.9.2.1
/home/sean/.ghc/i386-linux-7.4.2/package.conf.d
bytestring-0.10.0.2
So, on the basis that the system is always right and I am always wrong I
removed the local one in my home folder:
sean@sean-Dimension-4700 ~/Documents/haskell/usb $ ghc-pkg unregister
bytestring-0.10.0.2
and then tried again:
sean@sean-Dimension-4700 ~/Documents/haskell/usb $ ghc --make usb1.hs
Linking usb1 ...
sean@sean-Dimension-4700 ~/Documents/haskell/usb $ sudo ./usb1
Inspecting device: "Bus 005 Device 002"
libusbx: error [submit_bulk_transfer] submiturb failed error -1 errno=2
usb1: IOException ""
*
*
For me that *is* *success*, it fails because since I wrote it I read the
USB docs again and I have to "claim" the device before I can talk to the
endpoint but at least I am now focused on my goal of USB interaction with
the Hexwax chip again.
A big thanks to everybody, this list is once again proving to be awesome,
another happy user walks away :)
Thanks everybody, especially Karol, Alexander and David.
Sean Charles.
*PS: Yes, I am using a a Dell from 2004 because as much as I'd love to but
a shiny new iMac I cant bring myself to part with my trusty friend. Hell, I
even wrote my own computer language system with it and it's "good enough".
Shameless plug (http://feltweb.info, site written in FELT!) Still
under-way, doing "Java" with it of late, not finished yet because USB and
hardware is more fun right now!
*
On 27 February 2013 19:21, David McBride
You have this line in your code, but that doesn't correlate to the imports you listed.
BS.replicate 64 '\0'
import qualified Data.ByteString as B ( ByteString, packCStringLen, drop, length ) import qualified Data.ByteString.Internal as BI ( createAndTrim, createAndTrim' ) import qualified Data.ByteString.Unsafe as BU ( unsafeUseAsCStringLen )
So you must have imported Data.ByteString.Lazy as BS somewhere. Change that to B.replicate and it will probably work.
On Wed, Feb 27, 2013 at 11:41 AM, emacstheviking
wrote: Karol, Alexander,
Thanks for your feedback... I am still a little confused as I shall explain... first of all let's look at the prototype for 'writeInterrupt',
writeInterrupt :: DeviceHandle -> EndpointAddress -> WriteAction
To me, that reads a "takes a device handle and an endpoint address and returns a WriteAction", and to quote the WriteAction help text verbatim so there is no confusion:
type WriteAction = ByteString -> Timeout -> IO (Size, Status)Source
Handy type synonym for write transfers.
"A WriteAction is a function which takes a ByteString to write and a Timeout. The function returns an IO action which, when exectued(sic), returns the number of bytes that were actually written paired with a Status flag which indicates whether the transfer Completed or TimedOut."
Now let's move to my original code and the 'right' code...
action <- writeInterrupt handle endPoint let action = writeInterrupt handle endPoint
If I understand things correctly up to this point, my mistake was being too eager in using "<-", my mind at that point was obviously confusing the return value from WriteAction with the return type of writeInterrupt and I can see now that what I should have done was use "let" which captures the WriteAction that is returned which can be executed with the payload and the timeout on the next line:
(size, status) <- action payload 1000
On this line, the use of "<-" is what is required in order to cause the promised IO action to perform its duties and return me the tuple of data sent and status returned from the USB inner workings.
However, we now come to the new type checker error, and this one has me floored right now. Time and time again I find myself beating my head against a wall and tearing my hair out trying to understand the thousand-and-one variations on strings in Haskell! I even tried the "string-conversions" (convertString) package but decided to battle it out instead...
First the new code as edited in response to Karol:
testBoard :: Device -> DeviceHandle -> IO () testBoard dev handle = do
putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"" -- write 0x00 0x00 0x00 0x00, get back same...we need to pad the -- packet out to 64 bytes for a full-speed device... should probably -- get this (64) from the device configuration / description record -- for maximum portability!
let payload = BS.replicate 64 '\0'
let endPoint = EndpointAddress 0 Out let action = writeInterrupt handle endPoint (size, status) <- action payload 1000 return ()
And the new error:
usb1.hs:64:28: Couldn't match expected type `bytestring-0.9.2.1:Data.ByteString.Internal.ByteString' with actual type `ByteString' In the first argument of `action', namely `payload' In a stmt of a 'do' block: (size, status) <- action payload 1000
In the expression: do { putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\""; let payload = BS.replicate 64 '\NUL'; let endPoint = EndpointAddress 0 Out; let action = writeInterrupt handle endPoint; .... }
Where and why does it think that "Data.ByteString.Internal.ByteString" is the type of the first parameter to "action" which is quite clearly stated as being "ByteString" ??? I know that "String", the native type is 4-bytes and that ByteString (Strict) and ByteString (Lazy) are both 8-bit, which is great, and I understand that the strict version (at least to me) feels like the rightmatch to be using for data buffers for a USB transfer but why oh why oh why can't I understand why the type checker picked up "internal" somewhere along the way?
In the source code for WriteAction we have this:
type WriteAction = B.ByteString → Timeout → IO (Size, Status)
and at the top of the that source file:
-- from bytestring: import qualified Data.ByteString as B ( ByteString, packCStringLen, drop, length ) import qualified Data.ByteString.Internal as BI ( createAndTrim, createAndTrim' ) import qualified Data.ByteString.Unsafe as BU ( unsafeUseAsCStringLen )
So why is it trying to be "internal"! I have tried not to be lazy, I have read everything and looked everywhere before posting again. If it had said:
type WriteAction = BI.ByteString → Timeout → IO (Size, Status)
I would have understood but it doesn't does it ?! Can somebody explain for me so I can just get on and write my killer USB application please! LOL
:) Thanks, Sean.
On 27 February 2013 12:07, Karol Samborski
wrote: Hi Sean,
I think that your function for testing board should look like this:
testBoard :: Device -> DeviceHandle -> IO () testBoard dev handle = do putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"\n" -- write 0x00 0x00 0x00 0x00, get back same... let payload = pack "\x00\x00\x00\x00" let endPoint = EndpointAddress 0 Out let action = writeInterrupt handle endPoint (size, status) <- action payload 1000 return ()
You need to use let because writeInterrupt returns (Timeout -> ByteString -> IO (Size, Bool)) instead of IO (Timeout -> ByteString -> IO (Size, Bool))
Karol
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Yeah that's always a danger. I had a similar problem with different
versions of conduit being required by two different dependencies just the
other night. If you start to have this problem commonly, it could be
advisable to check out the hsenv package on hackage. That way your
playground won't impact your serious applications.
On Wed, Feb 27, 2013 at 4:06 PM, emacstheviking
HURRAH! I have finally got it to compile...
I manually deleted the broken packages (I play too much anyway so a tidy up was in order) and it still failed with:
[1 of 1] Compiling Main ( usb1.hs, usb1.o )
usb1.hs:64:28: Couldn't match expected type `bytestring-0.9.2.1:Data.ByteString.Internal.ByteString' with actual type `ByteString' In the first argument of `action', namely `payload' In a stmt of a 'do' block: (size, status) <- action payload 1000 In the expression: do { putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\""; let payload = BS.replicate 64 '\NUL'; let endPoint = EndpointAddress 0 Out; let action = writeInterrupt handle endPoint; .... } And I suddenly remembered that despite the clean up I still had two bytestring packages:
sean@sean-Dimension-4700 ~/Documents/haskell/usb $ ghc-pkg list bytestring /var/lib/ghc/package.conf.d bytestring-0.9.2.1 /home/sean/.ghc/i386-linux-7.4.2/package.conf.d bytestring-0.10.0.2
So, on the basis that the system is always right and I am always wrong I removed the local one in my home folder:
sean@sean-Dimension-4700 ~/Documents/haskell/usb $ ghc-pkg unregister bytestring-0.10.0.2
and then tried again:
sean@sean-Dimension-4700 ~/Documents/haskell/usb $ ghc --make usb1.hs Linking usb1 ...
sean@sean-Dimension-4700 ~/Documents/haskell/usb $ sudo ./usb1 Inspecting device: "Bus 005 Device 002" libusbx: error [submit_bulk_transfer] submiturb failed error -1 errno=2 usb1: IOException "" * * For me that *is* *success*, it fails because since I wrote it I read the USB docs again and I have to "claim" the device before I can talk to the endpoint but at least I am now focused on my goal of USB interaction with the Hexwax chip again.
A big thanks to everybody, this list is once again proving to be awesome, another happy user walks away :)
Thanks everybody, especially Karol, Alexander and David.
Sean Charles.
*PS: Yes, I am using a a Dell from 2004 because as much as I'd love to but a shiny new iMac I cant bring myself to part with my trusty friend. Hell, I even wrote my own computer language system with it and it's "good enough". Shameless plug (http://feltweb.info, site written in FELT!) Still under-way, doing "Java" with it of late, not finished yet because USB and hardware is more fun right now! *
On 27 February 2013 19:21, David McBride
wrote: You have this line in your code, but that doesn't correlate to the imports you listed.
BS.replicate 64 '\0'
import qualified Data.ByteString as B ( ByteString, packCStringLen, drop, length ) import qualified Data.ByteString.Internal as BI ( createAndTrim, createAndTrim' ) import qualified Data.ByteString.Unsafe as BU ( unsafeUseAsCStringLen )
So you must have imported Data.ByteString.Lazy as BS somewhere. Change that to B.replicate and it will probably work.
On Wed, Feb 27, 2013 at 11:41 AM, emacstheviking
wrote: Karol, Alexander,
Thanks for your feedback... I am still a little confused as I shall explain... first of all let's look at the prototype for 'writeInterrupt',
writeInterrupt :: DeviceHandle -> EndpointAddress -> WriteAction
To me, that reads a "takes a device handle and an endpoint address and returns a WriteAction", and to quote the WriteAction help text verbatim so there is no confusion:
type WriteAction = ByteString -> Timeout -> IO (Size, Status)Source
Handy type synonym for write transfers.
"A WriteAction is a function which takes a ByteString to write and a Timeout. The function returns an IO action which, when exectued(sic), returns the number of bytes that were actually written paired with a Status flag which indicates whether the transfer Completed or TimedOut."
Now let's move to my original code and the 'right' code...
action <- writeInterrupt handle endPoint let action = writeInterrupt handle endPoint
If I understand things correctly up to this point, my mistake was being too eager in using "<-", my mind at that point was obviously confusing the return value from WriteAction with the return type of writeInterrupt and I can see now that what I should have done was use "let" which captures the WriteAction that is returned which can be executed with the payload and the timeout on the next line:
(size, status) <- action payload 1000
On this line, the use of "<-" is what is required in order to cause the promised IO action to perform its duties and return me the tuple of data sent and status returned from the USB inner workings.
However, we now come to the new type checker error, and this one has me floored right now. Time and time again I find myself beating my head against a wall and tearing my hair out trying to understand the thousand-and-one variations on strings in Haskell! I even tried the "string-conversions" (convertString) package but decided to battle it out instead...
First the new code as edited in response to Karol:
testBoard :: Device -> DeviceHandle -> IO () testBoard dev handle = do
putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"" -- write 0x00 0x00 0x00 0x00, get back same...we need to pad the -- packet out to 64 bytes for a full-speed device... should probably -- get this (64) from the device configuration / description record -- for maximum portability!
let payload = BS.replicate 64 '\0'
let endPoint = EndpointAddress 0 Out let action = writeInterrupt handle endPoint (size, status) <- action payload 1000 return ()
And the new error:
usb1.hs:64:28: Couldn't match expected type `bytestring-0.9.2.1:Data.ByteString.Internal.ByteString' with actual type `ByteString' In the first argument of `action', namely `payload' In a stmt of a 'do' block: (size, status) <- action payload 1000
In the expression: do { putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\""; let payload = BS.replicate 64 '\NUL'; let endPoint = EndpointAddress 0 Out; let action = writeInterrupt handle endPoint; .... }
Where and why does it think that "Data.ByteString.Internal.ByteString" is the type of the first parameter to "action" which is quite clearly stated as being "ByteString" ??? I know that "String", the native type is 4-bytes and that ByteString (Strict) and ByteString (Lazy) are both 8-bit, which is great, and I understand that the strict version (at least to me) feels like the rightmatch to be using for data buffers for a USB transfer but why oh why oh why can't I understand why the type checker picked up "internal" somewhere along the way?
In the source code for WriteAction we have this:
type WriteAction = B.ByteString → Timeout → IO (Size, Status)
and at the top of the that source file:
-- from bytestring: import qualified Data.ByteString as B ( ByteString, packCStringLen, drop, length ) import qualified Data.ByteString.Internal as BI ( createAndTrim, createAndTrim' ) import qualified Data.ByteString.Unsafe as BU ( unsafeUseAsCStringLen )
So why is it trying to be "internal"! I have tried not to be lazy, I have read everything and looked everywhere before posting again. If it had said:
type WriteAction = BI.ByteString → Timeout → IO (Size, Status)
I would have understood but it doesn't does it ?! Can somebody explain for me so I can just get on and write my killer USB application please! LOL
:) Thanks, Sean.
On 27 February 2013 12:07, Karol Samborski
wrote: Hi Sean,
I think that your function for testing board should look like this:
testBoard :: Device -> DeviceHandle -> IO () testBoard dev handle = do putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"\n" -- write 0x00 0x00 0x00 0x00, get back same... let payload = pack "\x00\x00\x00\x00" let endPoint = EndpointAddress 0 Out let action = writeInterrupt handle endPoint (size, status) <- action payload 1000 return ()
You need to use let because writeInterrupt returns (Timeout -> ByteString -> IO (Size, Bool)) instead of IO (Timeout -> ByteString -> IO (Size, Bool))
Karol
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Wed, Feb 27, 2013 at 09:06:30PM +0000, emacstheviking wrote:
HURRAH! I have finally got it to compile...
I manually deleted the broken packages (I play too much anyway so a tidy up was in order) and it still failed with:
[1 of 1] Compiling Main ( usb1.hs, usb1.o )
usb1.hs:64:28: Couldn't match expected type `bytestring-0.9.2.1:Data.ByteString.Internal.ByteString' with actual type `ByteString'
Glad you got it to work! For future reference, the fact that the error message includes a package name and version number (bytestring-0.9.2.1:Data.ByteString.Internal.ByteString instead of just Data.ByteString.Internal.ByteString) is usually a very strong indication that the real problem is multiple versions of the package interfering with one another. -Brent

Thanks for assist Brent! (Always wanted to say that etc).
Well, this was the first time that it has ever happened to me and so I
guess I didn't appreciate the underlying cause.... once bitten and all that.
Thanks again everybody!
:)
On 27 February 2013 21:24, Brent Yorgey
On Wed, Feb 27, 2013 at 09:06:30PM +0000, emacstheviking wrote:
HURRAH! I have finally got it to compile...
I manually deleted the broken packages (I play too much anyway so a tidy up was in order) and it still failed with:
[1 of 1] Compiling Main ( usb1.hs, usb1.o )
usb1.hs:64:28: Couldn't match expected type `bytestring-0.9.2.1:Data.ByteString.Internal.ByteString' with actual type `ByteString'
Glad you got it to work! For future reference, the fact that the error message includes a package name and version number (bytestring-0.9.2.1:Data.ByteString.Internal.ByteString instead of just Data.ByteString.Internal.ByteString) is usually a very strong indication that the real problem is multiple versions of the package interfering with one another.
-Brent
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Hi Sean,
I'm the author of the Haskell usb package. I think it's great that
you're trying out the library and I'm glad you solved your problem!
I just wanted to say that I wouldn't bother naming the 'action' value in:
let action = writeInterrupt handle endPoint
(size, status) <- action payload 1000
just write:
(size, status) <- writeInterrupt handle endPoint payload 1000
unless of course you're planning to use the 'action' multiple times...
The reason I introduced the WriteAction type synonym was that there
are multiple functions which all write bytes:
writeControl :: DeviceHandle -> ControlAction WriteAction
writeBulk :: DeviceHandle -> EndpointAddress -> WriteAction
writeInterrupt :: DeviceHandle -> EndpointAddress -> WriteAction
and I wanted to make the similarity obvious in the type signature.
However, other users of the usb library had trouble understanding this
before so I'm considering just getting rid of the type synonym and
listing the arguments directly.
Let me know if you need more help with usb!
Cheers,
Bas
On 27 February 2013 17:41, emacstheviking
Karol, Alexander,
Thanks for your feedback... I am still a little confused as I shall explain... first of all let's look at the prototype for 'writeInterrupt',
writeInterrupt :: DeviceHandle -> EndpointAddress -> WriteAction
To me, that reads a "takes a device handle and an endpoint address and returns a WriteAction", and to quote the WriteAction help text verbatim so there is no confusion:
type WriteAction = ByteString -> Timeout -> IO (Size, Status)Source
Handy type synonym for write transfers.
"A WriteAction is a function which takes a ByteString to write and a Timeout. The function returns an IO action which, when exectued(sic), returns the number of bytes that were actually written paired with a Status flag which indicates whether the transfer Completed or TimedOut."
Now let's move to my original code and the 'right' code...
action <- writeInterrupt handle endPoint let action = writeInterrupt handle endPoint
If I understand things correctly up to this point, my mistake was being too eager in using "<-", my mind at that point was obviously confusing the return value from WriteAction with the return type of writeInterrupt and I can see now that what I should have done was use "let" which captures the WriteAction that is returned which can be executed with the payload and the timeout on the next line:
(size, status) <- action payload 1000
On this line, the use of "<-" is what is required in order to cause the promised IO action to perform its duties and return me the tuple of data sent and status returned from the USB inner workings.
However, we now come to the new type checker error, and this one has me floored right now. Time and time again I find myself beating my head against a wall and tearing my hair out trying to understand the thousand-and-one variations on strings in Haskell! I even tried the "string-conversions" (convertString) package but decided to battle it out instead...
First the new code as edited in response to Karol:
testBoard :: Device -> DeviceHandle -> IO () testBoard dev handle = do
putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"" -- write 0x00 0x00 0x00 0x00, get back same...we need to pad the -- packet out to 64 bytes for a full-speed device... should probably -- get this (64) from the device configuration / description record -- for maximum portability! let payload = BS.replicate 64 '\0'
let endPoint = EndpointAddress 0 Out let action = writeInterrupt handle endPoint (size, status) <- action payload 1000 return ()
And the new error:
usb1.hs:64:28: Couldn't match expected type `bytestring-0.9.2.1:Data.ByteString.Internal.ByteString' with actual type `ByteString' In the first argument of `action', namely `payload' In a stmt of a 'do' block: (size, status) <- action payload 1000
In the expression: do { putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\""; let payload = BS.replicate 64 '\NUL'; let endPoint = EndpointAddress 0 Out; let action = writeInterrupt handle endPoint; .... }
Where and why does it think that "Data.ByteString.Internal.ByteString" is the type of the first parameter to "action" which is quite clearly stated as being "ByteString" ??? I know that "String", the native type is 4-bytes and that ByteString (Strict) and ByteString (Lazy) are both 8-bit, which is great, and I understand that the strict version (at least to me) feels like the rightmatch to be using for data buffers for a USB transfer but why oh why oh why can't I understand why the type checker picked up "internal" somewhere along the way?
In the source code for WriteAction we have this:
type WriteAction = B.ByteString → Timeout → IO (Size, Status)
and at the top of the that source file:
-- from bytestring: import qualified Data.ByteString as B ( ByteString, packCStringLen, drop, length ) import qualified Data.ByteString.Internal as BI ( createAndTrim, createAndTrim' ) import qualified Data.ByteString.Unsafe as BU ( unsafeUseAsCStringLen )
So why is it trying to be "internal"! I have tried not to be lazy, I have read everything and looked everywhere before posting again. If it had said:
type WriteAction = BI.ByteString → Timeout → IO (Size, Status)
I would have understood but it doesn't does it ?! Can somebody explain for me so I can just get on and write my killer USB application please! LOL
:) Thanks, Sean.
On 27 February 2013 12:07, Karol Samborski
wrote: Hi Sean,
I think that your function for testing board should look like this:
testBoard :: Device -> DeviceHandle -> IO () testBoard dev handle = do putStrLn $ "Inspecting device: \"" ++ (show dev) ++ "\"\n" -- write 0x00 0x00 0x00 0x00, get back same... let payload = pack "\x00\x00\x00\x00" let endPoint = EndpointAddress 0 Out let action = writeInterrupt handle endPoint (size, status) <- action payload 1000 return ()
You need to use let because writeInterrupt returns (Timeout -> ByteString -> IO (Size, Bool)) instead of IO (Timeout -> ByteString -> IO (Size, Bool))
Karol
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (4)
-
Bas van Dijk
-
Brent Yorgey
-
David McBride
-
emacstheviking