[Haskell-cafe] seems like I'm on the wrong track
Perhaps someone could either (1) help me do what I'm trying to do, or (2) show me a better way. I have a problem that is very state-ful and I keep thinking of it as OO, which is driving me crazy. Haskell is several times harder to use than Python in this instance, probably because I'm doing it wrong. To give you a larger context, this problem is essentially compiling a description of music (my own) into a kind of music-machine-language (CSound). CSound is relatively untidy. In this one example, in a OO way of thinking, I have data called AssignedNumbers that assigns integers to unique strings and keeps track of the used integers and next available integer (the choice of available integer could follow a number of conventions so I wanted to hide that in an ADT.) So it has an associated function: getNumber :: String - AssignedNumbers - (Int,AssignedNumbers) What getNumber does is: - check if the string already has a number assigned to it. If so, return that number. - if not, pick the next available number. - in all cases, return the possibly changed state of AssignedNumbers Then in a larger data structure, it contains fields of type AssignedNumbers. Like data MusicStuff = MusicStuff { oscillatorNumbers :: AssignedNumbers , tableNumbers :: AssignedNumbers , ... } I'm using MusicStuff in a State monad, so I might write a function like doSomeMusicStuff :: String - String - State MusicStuff (Int,Int) doSomeMusicStuff aString1 aString2 = do ms - get (o1,newOscNums) = getNumber aString1 (oscillatorNumbers ms) (t1,newTabNums) = getNumber aString2 (tableNumbers ms) put ms { oscillatorNumbers = newOscNums , tableNumbers = newTabNums } return (o1,t1) For what it does, this is extremely verbose and filled with distracting visual content. And this is just a very simple example---my real problem is several times more state-ful. Is there a better way? Note that in Python it would be a method def doMusicStuff( self, s1, s2 ) : return (self.oscillatorNumbers.next(s1), self.oscillatorNumbers.next(s2)) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] better way to do this?
Duncan Coutts wrote: So you end up with pure functions like: shuffle :: RandomGen g = g - [x] - [x] Thanks for the help, Duncan. I'm confused on one point. Don't you always need the new state of the generator back? So wouldn't this need to be: shuffle :: RandomGen g = g - [x] - (g,[x]) Another approach is to hide the 'g' inside a monad. That's what MonadRandom is all about. eg: shuffle :: [x] - Rand [x] One tutorial mentions the class Gen in the Test.QuickCheck module. Is Rand a different class defined somewhere else? The tutorials above explain about the other random functions, for getting values of different types (not just Int) and restricted ranges of number etc. Of course at some point you want to seed the random number generator with some initial genuinely random value (not like the 12345 we used above). That is the only place in your random-handling code that needs to do IO. All the rest of it can be pure. What function gives you that initial random seed? (Grabs it from the system clock?) Thanks, Mike ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] better way to do this?
Michael P Mossey wrote: Also note that I added the Random class constraint to 'shuffle'. I haven't tested this but it might be necessary. Or not? Okay I figured this part out too. The members of the list you are shuffling have no class constraint on them because the 'shuffle' function is not generating or computing with them... only moving them around. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Doing people's homework?
I'm not really hip to the culture here so this is just an observation, but some of the recent questions posted to this list (and beginn...@haskell.org) look a lot like someone's homework. Is anyone here concerned about avoiding giving the full answer, or maybe it's really none of our business (we aren't responsible for anyone's learning process)? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] adding state in GUIs (qtHaskell)
I'm trying to learn qtHaskell. I realize few people on this list know anything about qtHaskell, but I have a question that probably relates to all GUIs as implemented in Haskell. I just need a hint that could help me figure out the next step, which I might be able to infer from the qtHaskell API. I don't think is any tutorial-type or step-by-step type documentation for qtHaskell. I have sent some questions to the author of qtHaskell, David Harley, but he hasn't responded yet, and anyway I don't want to trouble him every time I have a question, so I'm trying to infer as much as I can. The problem relates to state. In Qt, one adds state to a widget by subclassing it and adding new member variables. For example, I want to create a widget that responds to keypresses and remembers what keypresses have taken place. I'm totally stuck on this part, because Haskell doesn't have state. There must be some kind of Haskell call that adds state to a widget, but it is hard to figure out from the qtHaskell examples David provides. Thanks, Mike ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] adding state in GUIs (qtHaskell)
Been poking around. Maybe IORef has something to do with this? I found a qtHaskell example that seems to make use of IORef in order to accomplish something similar to what I want. Michael P Mossey wrote: I'm trying to learn qtHaskell. I realize few people on this list know anything about qtHaskell, but I have a question that probably relates to all GUIs as implemented in Haskell. I just need a hint that could help me figure out the next step, which I might be able to infer from the qtHaskell API. I don't think is any tutorial-type or step-by-step type documentation for qtHaskell. I have sent some questions to the author of qtHaskell, David Harley, but he hasn't responded yet, and anyway I don't want to trouble him every time I have a question, so I'm trying to infer as much as I can. The problem relates to state. In Qt, one adds state to a widget by subclassing it and adding new member variables. For example, I want to create a widget that responds to keypresses and remembers what keypresses have taken place. I'm totally stuck on this part, because Haskell doesn't have state. There must be some kind of Haskell call that adds state to a widget, but it is hard to figure out from the qtHaskell examples David provides. Thanks, Mike ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] can someone point me to more help about Database.HDBC.ODBC?
I'm trying to use Database.HDBC.ODBC to connect to a MySQL server, and I cannot figure out the docs. I want to establish a connection, and I know the server url, username, and password. According to these docs... http://software.complete.org/static/hdbc-odbc/doc//HDBC-odbc/Database-HDBC-ODBC.html ...I am supposed to pass a string to connectODBC. These docs do not explain the meaning of the passed string, but refer me to a microsoft document: http://msdn2.microsoft.com/en-us/library/ms715433(VS.85).aspx I cannot make any sense of this microsoft document. I guess I don't know enough about database interfaces in general. Can someone explain how to make a connect to a specific URL, or point me to some clearer docs? Thanks, Mike ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] the problem of design by negation
Richard O'Keefe wrote: Design-by-negativity can *be* a way of being creative. I've lost count of the number of times that I've been explaining to someone why something can't be done, and suddenly realised that one of the reasons was invalid and seen how to do it. The key is not whether you explore the design space from a positive end or from a negative end, but whether you *explore* it. Hi Richard, I think we using positive and negative in a bit of a different sense (which may be my fault for not explaining perfectly in the first post). There are both positive and negative *facts* about design. There are things you can do, and things you can't. These are facts. I'm referring more to a specific kind of process (a specific kind of exploration)---in my terms, design by negation means that you dominant activity in design in cutting away possibilities, and what's left (however awkward) is what you must build. I have done this by habit, but I would like to shift into a mode of design that is focused on construction rather than destruction---to view design as an opportunity to meet most goals by clever combining of facets. Thanks, Mike ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] tips on using monads
I've got one of those algorithms which threatens to march off the right edge (in the words of Goerzen et al). I need something like a State or Maybe monad, but this is inside the IO monad. So I presume I need StateT or MaybeT. However, I'm still (slowly) learning about monads from first principles. I thought I might present my code and get some pointers... maybe someone could actually show me how to rewrite it, which would be a neat way to see MaybeT and StateT in action. I'm hoping to get anything from a one-line response to a rewrite of my code. Anything will help. Here's the program: {- This is a program which starts with a document containing notes about software requirements (in a particular format) and puts them into a database. Notes include details such as the source of the requirement (who gave it), the topic(s) to which it pertains, the date, etc. I have written a parser to take a text document typed up by me during a meeting and parse it into a NoteRecord structure. Here is the structure: -} data NoteRecord = NoteRecord { recordSource :: String, -- Name of person who gave req. recordDate :: [Int], -- Date in [year,month,date] recordSourceType :: String, -- meeting, phone, email, etc. recordBugNum :: Maybe Int,-- Bugzilla # (if relevant) recordTopics :: [String], -- list of official topics pertaining recordText :: String }-- the text of the note itself deriving (Show) {- One other wrinkle. The source (person name) and topic must be one of a set of pre-determined strings. A person has an official full name which is stored in the database. Topics also have official descriptive strings. If I wasn't clever, then the note, as I type it up, must have the exact name and topic. But I hate trying to remember things like that. So I have implemented a fuzzy string match system so that I can type part of someone's name (or even misspell it) or part of a topic string, and the system will find the best match to an official string. In pseudocode, the function to insert a note in the database must do this: This function starts with a NoteRecord. - If text already exists in the database, give an error and skip to end. - Fuzzy-match strings to topics and source. - If no potential match can be found to some of topics or source, give error and skip to end. - Ask user to confirm if the matched topics and source look okay. - if user says no, skip to end. - Actually insert the record. -} insertNote :: NoteRecord - Connection - IO () insertNote nr conn = do -- Check if it exists in the database already. status - checkPreExistingText nr conn if status then putStrLn Skipping... text exists already. else do -- Find best fit for all topics and source. -- See type signatures below. bestFitTopics - fitTopics nr conn bestFitSource - fitSource nr conn case any isNothing bestFitTopics of True - putStrLn Error... some topic couldn't be matched. False - case bestFitSource of Nothing - putStrLn Error.. source couldn't be matched. _ - do b - isUserOkay nr bestFitTopics bestFitSource if b then do -- Create a new NoteRecord with matched -- and validated topics/source. nrValidated = nr { recordTopics = bestFitTopics , recordSource = bestFitSource } insertRow nrValidated conn else putStrLn Abort due to user request. checkPreExistingText :: NoteRecord - Connection - Bool -- There are multiple topics in the NoteRecord. For each one, -- find the best fuzzy match, or indicate if there is no plausible -- match at all. fitTopics :: NoteRecord - Connection - [Maybe String] -- There is one source. Try to find fuzzy match. fitSource :: NoteRecord - Connection - Maybe String -- Present user with all fuzzy matches and get a yes/no response if it's -- okay to proceed. isUserOkay :: NoteRecord - [Maybe String] - Maybe String - Bool -- Do actual insert into database. insertRow :: NoteRecord - Connection - IO () ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] subscribing to the comments, online Real World Haskell
I love that Real World Haskell is online, here: http://book.realworldhaskell.org/read/ I love that it has a comment section embedded with every paragraph. However, I would like some ability to subscribe to specific comments. I want to see if people have replied to me or what the latest discussion is. Anyone know if this is possible by a method other than manually copying down every URL? (In fact, I'm not sure that I can create a URL that goes directly to a part of a chapter.) Thanks, Mike ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] subscribing to the comments, online Real World Haskell
Michael P Mossey wrote: However, I would like some ability to subscribe to specific comments. I want to see if people have replied to me or what the latest discussion is. Okay, to follow up my own post, I discovered the subscription button for each chapter. That's good. However, using Live Bookmarks in Firefox, I have a problem... the links that should bring me to the book itself (with the comment in context) are broken. Maybe this is the fault of Live Bookmarks. Anyone recommend another program for subscribing to comments? -Mike ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] installing Sqlite3 driver for windows
I'm working from Real World Haskell, trying to install HDBC and the Sqlite3 driver on Windows XP. It was easy enough to use Cabal to install HDBC. However, for the Sqlite3 driver things get fuzzy. I downloaded hdbc-sqlite3_2.1.0.0.zip, but don't know what I'm supposed to do with it. Also, it wasn't clear what to do with the sqlite3.dll file. On this page http://software.complete.org/software/wiki/hdbc/FrequentlyAskedQuestions it seems to imply you need to put it in 'gch --print-libdir'\include and %windir%\system32 but that page is really about building the driver from source. Maybe it only needs to go in the system32 directory. Thanks, Mike ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Parsec question
I've just about got this parser working, but wondering about something. Turns out I need try inside the lookahead here. parseText :: Parser String parseText = manyTill anyChar $ lookAhead (try (string //)) Without try, if I give it an input with a single slash, like some/text It stops with the error unexpected t; expecting // I'm curious why that happens when lookAhead is used with manyTill like this. I was under the impression that if the end parser given to manyTill failed, then manyTill would just continue with the main parser. Apparently there are two ways to fail: in some contexts, failing means that manyTill will just continue. In other contexts, such as the one above, there is some sense in which 'string' demands the entire string to be present. Can anyone explain? Thanks, Mike ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Parsec question
I want to write a parser that can read a file with this format: the file has sections which are demarcated by keywords. Keywords always begin with two forward slashes and consist of letters, digits, and underscore. The text can be anything, including special characters. For instance: //keyword some text and more text //another_keyword and) some { more text //ya_keyword $$ -- text I'm not sure how to write a parser that considers anything but a double slash to be a valid part of the text. Thanks, Mike ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe