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

David McBride toad3k at gmail.com
Wed Feb 27 22:11:48 CET 2013


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 <objitsu at gmail.com> 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'
>     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 at 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 at sean-Dimension-4700 ~/Documents/haskell/usb $ ghc-pkg unregister
> bytestring-0.10.0.2
>
> and then tried again:
>
> sean at sean-Dimension-4700 ~/Documents/haskell/usb $ ghc --make usb1.hs
> Linking usb1 ...
>
> sean at 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 <toad3k at gmail.com> 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 <objitsu at gmail.com>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 <edv.karol at gmail.com> 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 at haskell.org
>>>> http://www.haskell.org/mailman/listinfo/beginners
>>>>
>>>
>>>
>>> _______________________________________________
>>> Beginners mailing list
>>> Beginners at haskell.org
>>> http://www.haskell.org/mailman/listinfo/beginners
>>>
>>>
>>
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://www.haskell.org/mailman/listinfo/beginners
>>
>>
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20130227/9c3d494f/attachment-0001.htm>


More information about the Beginners mailing list