How can i convert List in String in erlang?
My list view:
[{{19,59,51},{2011,1,14},"fff"},{{19,59,47},{2011,1,14},"ASDfff"}]
Thank you.
A very simple thing would be
List = [{{19,59,51},{2011,1,14},"fff"},
{{19,59,47},{2011,1,14},"ASDfff"}],
IOList = io_lib:format("~w", [List]),
FlatList = lists:flatten(IOList),
but as these appear to be timestamps which you may want to be formatted in a better way, something like
FormattedIOLists =
[ io_lib:format("~4..0B-~2..0B-~2..0B ~2..0B:~2..0B:~2..0B ~s",
[YYYY,M,D, HH,MM,SS, Comment])
|| {{HH,MM,SS},{YYYY,M,D},Comment} <- List ],
FormattedFlatLists =
[ lists:flatten(io_lib:format("~4..0B-~2..0B-~2..0B ~2..0B:~2..0B:~2..0B ~s",
[YYYY,M,D, HH,MM,SS, Comment]))
|| {{HH,MM,SS},{YYYY,M,D},Comment} <- List ],
could fit your bill better.
For quick and dirty interactive output on the shell,
9> [ io:format("~4..0B-~2..0B-~2..0B ~2..0B:~2..0B:~2..0B ~s~n", [YYYY,M,D, HH,MM,SS, Comment]) || {{HH,MM,SS},{YYYY,M,D},Comment} <- List ].
2011-01-14 19:59:51 fff
2011-01-14 19:59:47 ASDfff
[ok,ok]
10> lists:foreach(fun({{HH,MM,SS},{YYYY,M,D},Comment}) -> io:format("~4..0B-~2..0B-~2..0B ~2..0B:~2..0B:~2..0B ~s~n", [YYYY,M,D, HH,MM,SS, Comment]) end, List).
2011-01-14 19:59:51 fff
2011-01-14 19:59:47 ASDfff
11>
Note that in most cases building recursive lists of lists (iolists) is a much better thing to do than flattening those iolists. Most output functions directly accept iolists for output data, so you gain nothing by flattening the lists before the actualy output happens.
Maybe just:
io_lib:format("~w", [[{{19,59,51},{2011,1,14},"fff"},{{19,59,47},{2011,1,14},"ASDfff"}]]).
Related
Consider the following code snippet in Idris:
myList : List Int
myList = [
1,
2,
3
]
The closing delimiter ] is on the same column as the declaration itself. I find this a quite natural way to want to format long, multi-line lists.
However, the equivalent snippet in Haskell fails to compile with a syntax error:
myList :: [Int]
myList = [
1,
2,
3
]
>> main.hs:9:1: error:
>> parse error (possibly incorrect indentation or mismatched brackets)?
>> |
>> 9 | ]
>> | ^
And requires instead the the closing delimiter ] is placed on a column number strictly greater than where the expression is declared. Or at least, as far as I can garner, this seems to be what is going on.
Is there a reason Haskell doesn't like this syntax? I know there are some subtle interactions between the Haskell parser and lexer to enable Haskell's implementation of the offsides rule, so perhaps it has something to do with that.
Well, ultimately the answer is just “because the Haskell language standard demands it to be parsed this way”.
As to for some reasoning why this is a good idea, it's that indentation is the primary way code is structured, and parentheses/brackets only come in locally. I find this much more consequent than Python's attitude that indentation is kind of the primary structure, but for an expression to spread over multiple lines you actually need to wrap it in parentheses. (Not saying that these are the only two ways it could be done.)
Note that if you really want, you can always disable the indentation sensitivity completely, with something like
myList :: [Int]
myList = l where {
l = [
1,
2,
3
]}
But I would not recommend it. The preferred style to write multiline lists is
myList
= [ 1
, 2
, 3
]
or
myList = [ 1
, 2
, 3 ]
Again, I would argue that this leading-comma style is much preferrable to the trailing-comma one most programmers in other languages use, especially for nested lists: the commas become “bullet points” aligned with the opening bracket, which makes the AST structure very clear.
myMonstrosity :: [(Int, [([Int], Int)])]
= [ ( 1
, [ ( [37,43]
, 9 )
, ( [768,4,9807,3,4,98]
, 15 ) ]
)
, ( 2, [] )
, ( 3
, [ ( [], 300 )
, ( [0..4000], -5 ) ]
)
]
If I have a variable my $a = True, then I get this output from the following code:
say «a list of words foo $a bar baz».raku;
# OUTPUT: ("a", "list", "of", "words", "foo", "True", "bar", "baz")
That is, even though the result is a List, the element True is stringified before being included in the list – the list contains "True", not True. Is there any way to avoid that stringification while still using interpolation?
Would there be a way to do so if $a were a class I'd defined (and thus can write the Str method for) rather than a Bool?
(I am aware that I can write the more verbose ("a", "list", "of", "words", "foo", $a, "bar", "baz") or «a list of words foo».Slip, $a, «bar baz».Slip, but I'm asking if there is a way to still use interpolation).
Interpolation is putting a thing into a string.
"a b c $thing d e f"
It does that by first turning the thing itself into a string, and concatenating the rest of the string around it.
Basically the above compiles into this code:
infix:<~>( 「a b c 」, $thing.Str, 「 d e f」 )
« a b c $thing »
Is short for:
Q :double :quotewords « a b c $thing d e f »
That is use the Quoting DSL, turning on :double quote semantics (“”) and turning on :quotewords.
:quotewords is the feature which splits the string into its individual parts.
It happens only after it has been turned into a string.
Imagine that the above compiles into:
Internals::quotewords( infix:<~>( 「 a b c 」, $thing.Str, 「 d e f 」 ) )
There is another way to get what you want, other than using .Slip or prefix |.
flat «a list of words foo», $a, «bar baz»
The whole purpose of the quoting DSL is that it produces a string.
That said :words, :quotewords, and :val all change it so that it returns something other than a single string.
And the idea of them is that they alter the DSL.
So MAYBE you could convince enough people that such a change would be worth it.
Thats a big maybe.
It would potentially break many existing codebases, so you would have an uphill battle to do so.
What happens here has little to do with quoting, and a lot to do with context. As #brad-gilbert has indicated, anything that goes passes through putting ~ in front, which is coercing the variable to a String context.
But that yields an answer to your second question:
Would there be a way to do so if $a were a class I'd defined (and thus can write the Str method for) rather than a Bool?
Theoretically, something like this should work:
class A {
has Bool $.foo;
method Str { $.foo }
};
my $a = A.new( :foo(True) );
say «a b $a».raku
Alas, this returns «No such method 'WORDS_AUTODEREF' for invocant of type 'Bool' so it probably needs a bit of work (or I might have bumped into some bug). So this is, for the time being, and for your precise example, a nanswer. As a matter of fact, only Strs have that method, so I think that for the time being, and unless you bother to create that specialized method for a class, it's difficult to do.
I have a list of subjects and weekdays, on which the subject is taught.
subjectDays = [("maths", ["mon", "tue"]),
("science", ["mon", "wed"])]
Now I would like to generate a list of combinations.
The result should look like as follows.
combinations = [[("maths", "mon"), ("science", "mon")],
[("maths", "mon"), ("science", "wed")]
-- etc.
]
Could anyone please help me to write a function in Haskell to produce the above result?
Thank you very much in advance.
From the comment below, I now realize that you want another output than the one I initially understood.
Essentially, you want each sublist to contain each subject (exactly once), paired with one of its days. If we still take combinations as defined below (the "wrong" output) we realize that we want to take the "cartesian product" of all the lists inside combinations. This cartesian product can be obtained using Control.Monad.sequence.
wantedCombinations = sequence combinations
Here's a hint.
First, write a function to expand a single pair of yours into a list.
combs :: (a,[b]) -> [(a,b)]
combs (subject, days) = ...
This could be solved using a list comprehension, for instance. Or map.
Then, we can apply combs to each pair in the list
combinations = map combs subjectDays
write an expand function to work on a single pair
expand :: (a,[b]) -> [(a,b)]
expand (x,[]) = []
expand (x,(y:ys)) = (x,y): expand (x,ys)
map to your structure and take the transpose (Data.List)
transpose $ map expand subjectDays
I'm trying to mess about trying the haskell equivalent of the 'Scala One Liners' thing that has recently popped up on Reddit/Hacker News.
Here's what I've got so far (people could probably do them a lot better than me but these are my beginner level attempts)
https://gist.github.com/1005383
The one I'm stuck on is verifying if items are in a list. Basically the Scala example is this
val wordlist = List("scala", "akka", "play framework", "sbt", "typesafe")
val tweet = "This is an example tweet talking about scala and sbt."
(words.foldLeft(false)( _ || tweet.contains(_) ))
I'm a bit stumped how to do this in Haskell. I know you can do:
any (=="haskell") $ words "haskell is great!"
To verify if one of the words is present, but the Scala example asks if any of the words in the wordlist are present in the test string.
I can't seem to find a contains function or something similar to that. I know you could probably write a function to do it but that defeats the point of doing this task in one line.
Any help would be appreciated.
You can use the elem function from the Prelude which checks if an item is in a list. It is commonly used in infix form:
Prelude> "foo" `elem` ["foo", "bar", "baz"]
True
You can then use it in an operator section just like you did with ==:
Prelude> let wordList = ["scala", "akka", "play framework", "sbt", "types"]
Prelude> let tweet = "This is an example tweet talking about scala and sbt."
Prelude> any (`elem` wordList) $ words tweet
True
When you find yourself needing a function, but you don't know the name, try using Hoogle to search for a function by type.
Here you wanted something that checks if a thing of any type is in a list of things of the same type, i.e. something of a type like a -> [a] -> Bool (you also need an Eq constraint, but let's say you didn't know that). Typing this type signature into Hoogle gives you elem as the top result.
How about using Data.List.intersect?
import Data.List.intersect
not $ null $ intersect (words tweet) wordList
Although there are already good answers I thought it'd be nice to write something in the spirit of your original code using any. That way you get to see how to compose your own complex queries from simple reusable parts rather than using off-the-shelf parts like intersect and elem:
any (\x -> any (\y -> (y == x)) $ words "haskell is great!")
["scala", "is", "tolerable"]
With a little reordering you can sort of read it in English: is there any word x in the sentence such that there is any y in the list such that x == y? It's clear how to extend to more 'axes' than two, perform comparisons other than ==, and even mix it up with all.
I'm doing a program in Haskell (on the Haskell platform), and I know I'm getting perfectly formatted inputs, so the input may look like
[ ['a'], ['b'], ['c'] ]
I want Haskell to be able to take this and use it as a list of it's own. And, I'd like this list to be over multiple lines, i.e., I want this to also work:
[
['a'],
['b'],
['c']
]
I can parse this input, but I've been told there's a way to do this easily - this is supposed to be the 'trivial' part of the assignment, but I don't understand it.
read "[ ['a'], ['b'], ['c'] ]" :: [[Char]]
will return [ ['a'], ['b'], ['c'] ]. If you assign the result of read to a variable that can be inferred to be of type [[Char]], you don't need the :: [[Char]] bit.
There is an instance of the Read class for Haskell lists, meaning you can use the read function to effectively parse strings formatted like Haskell lists, which is exactly what you have.