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

David McBride toad3k at gmail.com
Wed Feb 27 20:21:20 CET 2013


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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20130227/e10949dd/attachment.htm>


More information about the Beginners mailing list