I have a function that receives a list of strings and concatenates each string into a new string, i do that using Enum.join. But when i try this operation, i get the following error:
** (Protocol.UndefinedError) protocol Enumerable not implemented for "int main(){return 2;}" of type BitString. This protocol is implemented for the following type(s): Date.Range, File.Stream, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, List, Map, MapSet, Range, Stream
My way around this was trying to convert the BitString into a String, but i can't find anything for doing this in Elixir's documentation.
My other solution was trying to not get that BitString at all but i don't even know why i'm getting that BitString to begin with.
The process i'm doing is to receive a list like this: [{"int main(){return 2;}", 1}]
Then i make a list but only using the string text=Enum.map(words, fn {string, _} -> string end)
I tried printing the result so i'm sure i'm giving the correct argument; by using IO.inspect(text), i got ["int main(){return 2;}"], which looks like a list of strings to me.
Then i pass that to a function using Enum.flat_map(text, &lex_raw_tokens(&1, line))
Inside of that function, i do
def lex_raw_tokens(program,line) when program != "" do
textString=Enum.join(program, " ")
This is where i get the error. Is there any way of turning that BitString back into a String or not get that BitString?
Sorry, i'm still learning Elixir and honestly so far it's the most dificcult lenguage i've learned and i'm having a lot of troubles with it. Also, this whole thing is part of a small C compiler i'm doing as a school proyect
You have text bound to ["int main(){return 2;}"], then you're doing an Enum.flat_map/2 over text, so inside lex_raw_tokens/2, program is bound to "int main(){return 2;}". You're then trying to do an Enum.join/2 on program, but since it's a string (which is a kind of BitString), it's not enumerable.
Related
we have a function bool_to_string(flag) and you're supposed to define it so that the bool value passed to the function i.e flag is always returned as a string.
bool_to_string = str
This was a valid answer but I don't understand how it works. I know about lambda but this doesn't appear to be that. Can someone explain to me how it is so short?
edit: like the person below highlighted, our original function was just converting a value to string. That is the same the built-in function str() does so we have just swapped out our original function with str. Simple and clean solution.
The expression creates a new function bool_to_string and assigns it the value of function str. In essence, bool_to_string is an alias for the str function.
In Python, everything is an object you can work with functions in the same way as with any other data type.
I am writing the following simple routine:
program scratch
character*4 :: word
word = 'hell'
print *, concat(word)
end program scratch
function concat(x)
character*(*) x
concat = x // 'plus stuff'
end function concat
The program should be taking the string 'hell' and concatenating to it the string 'plus stuff'. I would like the function to be able to take in any length string (I am planning to use the word 'heaven' as well) and concatenate to it the string 'plus stuff'.
Currently, when I run this on Visual Studio 2012 I get the following error:
Error 1 error #6303: The assignment operation or the binary
expression operation is invalid for the data types of the two
operands. D:\aboufira\Desktop\TEMP\Visual
Studio\test\logicalfunction\scratch.f90 9
This error is for the following line:
concat = x // 'plus stuff'
It is not apparent to me why the two operands are not compatible. I have set them both to be strings. Why will they not concatenate?
High Performance Mark's comment tells you about why the compiler complains: implicit typing.
The result of the function concat is implicitly typed because you haven't declared its type otherwise. Although x // 'plus stuff' is the correct way to concatenate character variables, you're attempting to assign that new character object to a (implictly) real function result.
Which leads to the question: "just how do I declare the function result to be a character?". Answer: much as you would any other character variable:
character(len=length) concat
[note that I use character(len=...) rather than character*.... I'll come on to exactly why later, but I'll also point out that the form character*4 is obsolete according to current Fortran, and may eventually be deleted entirely.]
The tricky part is: what is the length it should be declared as?
When declaring the length of a character function result which we don't know ahead of time there are two1 approaches:
an automatic character object;
a deferred length character object.
In the case of this function, we know that the length of the result is 10 longer than the input. We can declare
character(len=LEN(x)+10) concat
To do this we cannot use the form character*(LEN(x)+10).
In a more general case, deferred length:
character(len=:), allocatable :: concat ! Deferred length, will be defined on allocation
where later
concat = x//'plus stuff' ! Using automatic allocation on intrinsic assignment
Using these forms adds the requirement that the function concat has an explicit interface in the main program. You'll find much about that in other questions and resources. Providing an explicit interface will also remove the problem that, in the main program, concat also implicitly has a real result.
To stress:
program
implicit none
character(len=[something]) concat
print *, concat('hell')
end program
will not work for concat having result of the "length unknown at compile time" forms. Ideally the function will be an internal one, or one accessed from a module.
1 There is a third: assumed length function result. Anyone who wants to know about this could read this separate question. Everyone else should pretend this doesn't exist. Just like the writers of the Fortran standard.
after a lot of trial/error and the search function I am still somewhat clueless about an I-thought-simple-thing (as always, hrmpf):
I have a column in a data frame x$question and within that column, there is an expression 'A/V' every once in a while, and I simply want it to be changed to 'A / B'.
I tried a little here and there, and thought this should work:
x$question[agrep('A/V',x$question)]<-'A / B'
but I get the error:
In `[<-.factor`(`*tmp*`, agrep('A/V', :
invalid factor level, NAs generated
or I could do this
agrep('A/V','A / B', x$question).
But here I get the error:
Error in .amatch_bounds(max.distance) :
match distance components must be non-negative
Since I am quite out of ideas, I would be very thankful, if you had a suggestions, or maybe an even simpler way of replacing a string with another string.
Does this work?
gsub("A/V","A/B",x$question)
Example:
x<-c("A/V", "A/V", "A/V")
x<-gsub("A/V","A/B",x)
>x
[1] "A/B" "A/B" "A/B"
Note: You can use ifelse for that too.
> ifelse(x=="A/B","A/V",x)
[1] "A/V" "A/V" "A/V"
I'm having trouble checking whether two strings are equal when one of them was passed through a splat argument. Because coffeescript uses strict comparisons, and because it makes a copy of the arguments when they go through a splat, I can't get the strings to compare properly without resorting to backticks. Is there a better way? Here's a minimal piece of code that demonstrates the problem:
check=(arg) ->
if arg == 'foo' then "'#{arg}'=='foo'" else "'#{arg}'!='foo'"
emit=(args...) ->
check(args)
console.log(emit('foo'))
console.log(check('foo'))
The output from this will be as follows:
> coffee mincase.coffee
'foo'!='foo'
'foo'=='foo'
EDIT:
mu is too short gave me the key, so the revised working code looks like this (everything is the same except emit)
emit=(args...)->
check.apply(null,args)
When you use a splat, the splat puts the splatted arguments into an array. For example:
f = (x...) -> console.log(x instanceof Array)
f(6)
will give you a true in the console. The fine manual isn't so fine in this case, it doesn't exactly spell it out, it assumes that you understand how JavaScript's arguments object works and leaves out the explicit splat puts your arguments into an array part.
So you end up passing an array to check and an array compared with a string using CoffeeScript's == (or JavaScript's ===) will never be true.
If you want emit to check the first argument, then you need to say so:
emit = (args...) -> check(args[0])
Demo: http://jsfiddle.net/ambiguous/TBndM/
The following allows to convert a tuple or object back to an object in erlang:
{ok, Tokens, _} = erl_scan:string("{'abc',123}."),
{ok, X} = erl_parse:parse_term(Tokens).
But when you have a record represented as a string, such as:
-record(myrecord,{firstname,lastname,age}).
...
RecString = "#myrecord{firstname='john',lastname='doe',age=22}.",
{ok, Tokens, _} = erl_scan:string(RecString),
{ok, X} = erl_parse:parse_term(Tokens).
... the above will fail with the message:
** exception error: no match of right hand side value {error,{1,erl_parse,["syntax error before: ",[]]}}
Thoughts on how to achieve that? Thanks.
First you must remember that a record does not exist as a data-type, internally records are tuples where the first element is the name of the record. So with your record definition:
-record(myrecord,{firstname,lastname,age}).
the creating the record with
#myrecord{firstname='john',lastname='doe',age=22}
would result in the tuple
{myrecord,john,doe,22}
which just contains the actual data. This is how records are defined, see here.
Second point is that records are purely compile-time syntactic constructions which compiler transforms in tuple operations. So the definition of a record does not exist as such as data anywhere. Only the compiler knows of record definitions. So when you print a record all you see is the tuple. However you can define record inside the shell so you can use record syntax in the shell, see in the shell documentation.
So in this sense you cannot really convert a record to/from its string representation. You can parse the string but this only returns the abstract syntax which is not what you are after. They are expressions so you need to end the string with a . and use erl_parse:exprs/1.
Hope this helps. What are you trying to do? Or rather why are you trying to do it?