Clojure: convert a string to map - dictionary

Do you know a function that takes a Clojure string and converts it to a map. For example, if the function gets the string
:first "John" :last "Lukas" :city "London"
it returns a map with the previous key-value relations.

You can use the clojure.end/read-string function for this. It makes sure that nobody injects code to your system, but otherwise will parse clojure data structures. Prepend "{" and append "}" to make it a map, that can be parsed that way:
(def stringtoparse ":first \"John\" :last \"Lukas\" :city \"London\"")
(clojure.edn/read-string (str "{" stringtoparse "}"))

Related

Suppress empty result from 'many' in 'seq(p, many(p))' construct with parser combinators

I'm trying to build parser combinators following Hutton and Meijer, "Monadic Parser Combinators". My implementation is in PostScript, but I think my issue is general to combinator parsers and not my specific implementation.
As a small exercise, I'm using the parsers to recognize regular expressions.
(pc9.ps)run
/Dot (.) char def
/Meta (*+?) anyof def
/Character (*+?.|()) noneof def
/Atom //Dot
//Character plus def
/Factor //Atom //Meta maybe seq def
/Term //Factor //Factor many seq def
/Expression //Term (|) char //Term xthen many seq def
/regex { string-input //Expression exec ps } def
(abc|def|ghi) regex
quit
It's working, but the output has lots of [] empty arrays that really get in the way when I try to bind handlers to process the values.
$ gsnd -q -dNOSAFER pc9re2.ps
stack:
[[[[[97 []] [[98 []] [[99 []] []]]] [[[100 []] [[101 []] [[102 []]
[]]]] [[[103 []] [[104 []] [[105 []] []]]] []]]] null]]
These are happening whenever a seq sequencing combinator accepts the result from maybe or many (which uses maybe) that had zero occurrences.
What is the normal way of excluding this extra noise in the output with Parser Combinators?
github repo
Sigh. It's seems I can just implement around it. I added special code in seq to detect an empty right-hand-side and just discard it. On to other problems...
Edit: I encountered the same problem again in version 11 (and a half). Now I've got a better solution IMO:
https://groups.google.com/g/comp.lang.functional/c/MbJxrJSk8Mw/m/MoT3Dr0IAwAJ
Ugh. I think it wasn't even an X/Y problem. It was a "doctor it hurts
when I move my arm like this; ... so don't move your arm like that"
problem.
I want the "result" part of the "reply" structure (using new terms
following usage from the Parsec document) to be any of the /usual/
PostScript types: integer, real, string, boolean, array, dictionary.
But I also need some way to arbitrarily combine or concatenate two
objects regardless of type. My then (aka seq) combinator needs to
do this. So I made a hack-y function that does the combining. If it
has two arrays, it composes the contents into a longer array. If it
has one array and some other object it extends the array by one and
stuffs the object in the front or back as appropriate. If it has two
non-array objects it makes a new 2-element array to contain them.
So, instead of building xthen and thenx off of then and needing
to cons, car, and cdr the stuff, I can write all 3 of these as a more
general parameterized function.
sequence{ p q u }{
{ /p exec +is-ok {
next x-xs force /q exec +is-ok {
next x-xs 3 1 roll /u exec exch consok
}{
x-xs 3 2 roll ( after ) exch cons exch cons cons
} ifelse
} if } ll } #func
then { {append} sequence }
xthen { {exch pop} sequence }
thenx { {pop} sequence }
append { 1 index zero eq { exch pop }{
dup zero eq { pop }{
1 index type /arraytype eq {
dup type /arraytype eq { compose }{ one compose } ifelse
}{ dup type /arraytype eq { curry }{ cons } ifelse } ifelse } ifelse } ifelse }
(#func is my own non-standard extension to PostScript that takes a
procedure body and list of parameters and wraps the procedure with
code that defines the arguments in a local dictionary. ll is my
hack-y PostScript way of making lambdas with hard-patched parameters,
it's short for load all literals.)
The code also treats executable arrays (ie. PostScript procedures) as
a non-array for the purpose of combining sequences of results. This allows
the parser to be used as a syntax-directed compiler producing procedures
as output.

Remove white space between words in a handlebar expression

I’ve a handlebar expression which is giving me a dynamic string. I want to remove the white space between letters and use it as a div id. I know I can do this using JS. But is there a way to do this within handlebar template?
{{name}} is giving me “abc xyz” and I want “abcxyz” string.
What you can do is register a helper yourself and use it in your template to replace the white-space in the string with nothing.
Handlebars.js has a function registerHelper(String, Function) which (as you see) takes a string (the name of your helper) and a function that will return the result of your helper.
For example, if we want a helper function that replaces "Facebook" with "Google" in a given string you could do something like this.
Handlebars.registerHelper('replace', function(string) {
return string.replace('Facebook', 'Google');
});
In the template we would invoke it like {{replace "Hello, Facebook!"}} and it would return Hello, Google!.
In case of a multipurpose function (what it obviously should be in this case instead of the example I gave) you would pass the string to invoke the replacement on, the string to replace and what it should be replaced with.
Handlebars.registerHelper('replace', function(string, search, replace) {
return string.replace(search, replace);
});
In the same way as we did before we would invoke it in the template using {{replace "Hello, Facebook!" "Facebook" "Google"}}.
If you want to avoid writing your own helpers. You can use the following module : https://github.com/helpers/handlebars-helpers
simply install it
npm install --save handlebars-helpers
And you're good to go, you can use the following helper for your issue :
{{replace name " " ""}}
Here's another usage example :
{{replace "a b a b a b" "a" "z"}}
<!-- results in: 'z b z b z b' -->

Create a dictionary in clojure

I want to create a json representation of one known key and variable amount of unknown:
(defn test1 [var1 & var2]
(print json/write-str :key1 var1 var2))
(defn -main [& args]
(test1 "key1_val" {:key2 "val2" :key3 "val3"}))
It returns this:
:key1 key1_val ({:key2 val2, :key3 val3})
I want it to be a single dictionary. I wonder, is what the method returned really what I'm looking for? I think not because the 2nd part is in the parentheses.
(print json/write-str :key1 var1 var2)
This prints the function value of json/write-str, followed by the value of each of the keys. In clojure if you want a function to run, you must apply it, this is usually done by wrapping it in parenthesis.
Next, write-str takes multiple args, but the only arg that is turned into json is the first, so you need to wrap your data in a data structure.
I'm not sure how you really want the data structured, but something like this is closer I think:
(json/write-str {:key1 [var1 var2]})
Also, as a minor note, the code did not return :key1 key1_val ({:key2 val2, :key3 val3}), it printed the string ":key1 key1_val ({:key2 val2, :key3 val3})", and returned nil, because println always returns nil.

Pulling out a column in all records in a Sqlite table into a concatenated string in Haskell with Persist

I'm trying to learn Haskell, specifically Snap, Blaze HTML5 and Persist. I would like to take every row in a table, select a single column from it, and then concatenate the values into a single string.
I've previously worked with C#'s LINQ quite extensively and under Entity Framework I could do it like this:
String.Join(", ", dbContext.People.Select(p => p.Name));
This would compile down to SELECT Name FROM People, with C# then concatenating those rows into a string with ", " in between.
To try and get the concatenation part right, I put this together, which seems to work:
intercalate ", " $ map show [1..10]
(it counts 1-9, concatenates with ", " in between the items)
However, I can't get this to work with Database.Persist.Sqlite. I'm not sure I quite understand the syntax here in Haskell. To contact the DB and retrieve the rows, I have to call: (as far as I understand)
runSqlite "TestDB" $ selectList ([] :: [Filter Person]) [] 0 0
The problem is that I'm not sure how to get the list out of runSqlite. runSqlite doesn't return the type I'm after, so I can't use the return value of runSqlite. How would I do this?
Thank you for reading.
To clarify:
Snap requires that I define a function to return the HTML I wish to send back to the client making the HTTP request. This means that:
page = runSqlite "TestDB" $ do
{pull data from the DB)
Is no-go as I can't return the data via the runSqlite call, and as far as I know I can't have a variable in the page function which is set within the runSqlite do block. All examples I can find just write to IO in the runSqlite do block, which is not what needs to be done here.
The type of runSqlite is:
runSqlite :: (MonadBaseControl IO m, MonadIO m) => Text -> SqlPersistT (NoLoggingT (ResourceT m)) a -> m a
And the type of selectList is:
[Filter val] -> [SelectOpt val] -> m [Entity val]
So, you can actually, use the nice do notation of Monad, to extract it:
runSqlite "TestDB" $ do
myData <- selectList ([] :: [Filter Person]) [] 0 0
-- Now do stuff with myData
The <- thing gets the list out of the monad. I would suggest you to go through this chapter to get an idea of how Persistent is used. Note that the chapters in the book assume a basic Haskell understanding.
The issue is that I want to use the selectList outside of runSqlite as
I need to pass the concatenated string to a Blaze HTML5 tag builder:
body $ do p (concatenated list...)
For this case, just define a function that does your intended task:
myLogic :: [SqlColumnData] -> String -- Note that SqlColumnData is hypothetical
myLogic xs = undefined
And then just call them appropriately in your main function:
main = runSqlite "TestDB" $ do
myData <- selectList ([] :: [Filter Person]) [] 0 0
let string = myLogic myData
-- do any other remaining stuff
It hadn't clicked that if I didn't use a do block with runSqlite, the result of the last call in the statement was the return value of the statement - this makes total sense.
https://gist.github.com/egonSchiele/5400694
In this example (not mine) the readPosts function does exactly what I'm after and cleared up some Haskell syntax confusion.
Thank you for your help #Sibi.

How to get a string from TextIO in sml/ml?

I'm trying to read text from a file in SML. Eventually, I want a list of individual words; however, I'm struggling at how to convert between a TextIO.elem to a string. For example, if I write the following code it returns a TextIO.elem but I don't know how to convert it to a string so that I can concat it with another string
TextIO.input1 inStream
TextIO.elem is just a synonym for char, so you can use the str function to convert it to a string. But as I replied to elsewhere, I suggest using TextIO.inputAll to get a string right away.
Here is a function that takes an instream and delivers all (remaining) words in it:
val words = String.tokens Char.isSpace o TextIO.inputAll
The type of this function is TextIO.instream -> string list.

Resources