Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Re: Parsec lexeme parsers and whitespace/eol characters
(Brent Yorgey)
2. Converting a function to -> Writer w a (Franco)
3. Re: Converting a function to -> Writer w a (David McBride)
4. Re: System.USB.writeInterrupt -- confused by error message
from type system (Bas van Dijk)
----------------------------------------------------------------------
Message: 1
Date: Wed, 6 Mar 2013 15:17:47 -0500
From: Brent Yorgey <[email protected]>
Subject: Re: [Haskell-beginners] Parsec lexeme parsers and
whitespace/eol characters
To: [email protected]
Cc: Sean Cormican <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
On Mon, Mar 04, 2013 at 10:13:37AM +0000, Sean Cormican wrote:
> Hi Brent,
>
> I have been trying to use Parsec because there is more documentation and
> tutorials on using it.
>
> I am extremely limited as a functional programmer and just as bad as an
> actual programmer. I am currently 18 days away from the due date for this
> project and I have made little or no progress due to my lack of ability,
> would src-exts be difficult to pick up and use?
haskell-src-exts works extremely well, and it's not too hard to find
your way around it using the Haddock documentation. Start here:
http://hackage.haskell.org/packages/archive/haskell-src-exts/1.13.5/doc/html/Language-Haskell-Exts.html
Use one of the functions listed on that page to parse the file, and
then click on the types to take you to pages explaining what you get
back. For example, if you use parseFile you can see that you get back
a (ParseResult Module). Clicking on ParseResult, you can see that a
(ParseResult Module) is either (ParseOk m) where m is a Module, or
ParseFailed containing an error message. So you can pattern-match to
find out which. Then clicking on Module, you can see all the stuff
contained in a value of type Module. Keep clicking on types to learn
what they are.
The biggest difficulty is that since this is a parser for *all of*
Haskell, there will be *lots* of stuff that you don't care about. But
it might still be easier than trying to write your own parser; I am
not sure.
-Brent
------------------------------
Message: 2
Date: Wed, 6 Mar 2013 21:22:09 +0000
From: Franco <[email protected]>
Subject: [Haskell-beginners] Converting a function to -> Writer w a
To: [email protected]
Message-ID: <20130306212209.GA31213@efikamx>
Content-Type: text/plain; charset=us-ascii
I am trying to get comfortble with the various monads, just to hone my tools
for a better tomorrow.
> import Control.Monad.Writer
> import Data.Char ( toLower )
> import Text.Regex.Posix ( (=~) )
So I decided to code a very small example to 'get into it'. The following
code is extremely simple. Given a string, it will find all occourences of
a specific regexp, replace them, and return the changed string back.
> replaceStuff :: String -> String
> replaceStuff "" = ""
> replaceStuff cs = let (pre, found, post) = cs =~ pattern in
> pre ++ transf found ++ replaceStuff post
> where pattern = "[A-E]" -- some regExp pattern
> transf = map toLower -- placeholder function
> main :: IO ()
> main = putStrLn $ replaceStuff "this is thE Story of peter"
Yay, it works! Now let's talk about the Writer monad. I would like to have
a mini log via the writer monad (could be anything , probably "x found and
replaced with y")
> type Log = String
But after that I have no idea how to add the writer monad to my simple
but recursive function. Type sig will be something like
replaceCols :: String -> Writer Log String
but I don't know how to replace this part of the non monadic code
pre ++ transf found ++ replaceStuff post
I wrote this before giving up
writer ((pre ++ found ++ ??whathere??),
(found ++ " found\n")) >>
Probably I am no "getting it", so any help is appreciated! Thanks
-F
------------------------------
Message: 3
Date: Wed, 6 Mar 2013 16:51:19 -0500
From: David McBride <[email protected]>
Subject: Re: [Haskell-beginners] Converting a function to -> Writer w
a
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
Message-ID:
<can+tr43nzfchnibzvzxjf2bct0hgk15oargn+ntbru+a6y-...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"
It is a little bit roundabout, but here's how you would do a direct
translation:
import Control.Monad.Writer
import Data.Char ( toLower )
import Text.Regex.Posix ( (=~) )
replaceStuff :: String -> Writer [String] String
replaceStuff "" = return ""
replaceStuff cs = do
let (pre, found, post) = cs =~ pattern
tell ["found:" ++ found]
moreStuff <- replaceStuff post
return $ pre ++ transf found ++ moreStuff
where pattern = "[A-E]" -- some regExp pattern
transf = map toLower -- placeholder function
main = print $ runWriter $ replaceStuff "this is thE Story of peter"
Other than running runWriter, just remember everything that was pure now
must be a monad, so return everything. Also when you recurse that is also
now monadic. It now prints instead of putStrLn because it must return a
tuple. Everything else is pretty much the same.
On Wed, Mar 6, 2013 at 4:22 PM, Franco <[email protected]> wrote:
> I am trying to get comfortble with the various monads, just to hone my
> tools
> for a better tomorrow.
>
> > import Control.Monad.Writer
>
> > import Data.Char ( toLower )
> > import Text.Regex.Posix ( (=~) )
>
> So I decided to code a very small example to 'get into it'. The following
> code is extremely simple. Given a string, it will find all occourences of
> a specific regexp, replace them, and return the changed string back.
>
> > replaceStuff :: String -> String
> > replaceStuff "" = ""
> > replaceStuff cs = let (pre, found, post) = cs =~ pattern in
> > pre ++ transf found ++ replaceStuff post
> > where pattern = "[A-E]" -- some regExp pattern
> > transf = map toLower -- placeholder function
>
> > main :: IO ()
> > main = putStrLn $ replaceStuff "this is thE Story of peter"
>
> Yay, it works! Now let's talk about the Writer monad. I would like to have
> a mini log via the writer monad (could be anything , probably "x found and
> replaced with y")
>
> > type Log = String
>
> But after that I have no idea how to add the writer monad to my simple
> but recursive function. Type sig will be something like
>
> replaceCols :: String -> Writer Log String
>
> but I don't know how to replace this part of the non monadic code
>
> pre ++ transf found ++ replaceStuff post
>
> I wrote this before giving up
>
> writer ((pre ++ found ++ ??whathere??),
> (found ++ " found\n")) >>
>
> Probably I am no "getting it", so any help is appreciated! Thanks
>
> -F
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20130306/ed3aca9a/attachment.html>
------------------------------
Message: 4
Date: Thu, 7 Mar 2013 00:13:19 +0100
From: Bas van Dijk <[email protected]>
Subject: Re: [Haskell-beginners] System.USB.writeInterrupt -- confused
by error message from type system
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>,
emacstheviking <[email protected]>
Message-ID:
<cadlz5wx7pbi74ex6njl_4eijmnwsffhnxk6gcb7szsc_p+g...@mail.gmail.com>
Content-Type: text/plain; charset=UTF-8
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 <[email protected]> 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 <[email protected]> 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
>> [email protected]
>> http://www.haskell.org/mailman/listinfo/beginners
>
>
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 57, Issue 6
****************************************