I am trying:
import System.IO
saveArr = do
outh <- openFile "test.txt" WriteMode
hPutStrLn outh [1,2,3]
hClose outh
but it doesn't works... output:
No instance for (Num Char) arising from the literal `1'
EDIT
OK hPrint works with ints but what about float number in array? [1.0, 2.0, 3.0]?
hPutStrLn can only print strings. Perhaps you want hPrint?
hPrint outh [1,2,3]
Arrays, Lists and Strings exists only in imagination of programmer and as a term in some languages.
File is a sequence of bytes, so when you want to write something to it you should encode that imaginary String/List/Array into sequence of bytes (by show or by something from Storable etc).
As well terminal is a sequence of bytes which is encoded representation of actions needed to show something to user.
You have many ways to encode. You can make CSV representation of array by foldr (\a b -> a (',' : b)) "\n" (map shows [1,2,3]) or you may want to print it show [1,2,3]
derive Binary for your type, then write the data in binnary form using 'encodeFile' from the Data.Binary package. This is similar to writing the data out as a bytestring.
Related
I am a complete beginner to Haskell but I'm being asked to create a sudoku solver. I've been making some steady progress with it but one of the things it is asking me to do is print a valid representation of a sudoku puzzle s. The Puzzle data type is defined as a list of lists, so [[Maybe Int]] and this is composed of Block values ([Maybe Int], representing a row).
Function signature is this:
printPuzzle :: Puzzle -> IO ()
How do I output this? I know this may be a simple question and I'm missing the point but I'm still not at the stage where I've got my ahead around the syntax yet. Any help would be much appreciated!
Simple pretty-printing of this can be done really succinctly with something like the following:
import Data.Char (intToDigit)
showRow :: [Maybe Int] -> String
showRow = map (maybe ' ' intToDigit)
showPuzzle :: [[Maybe Int]] -> [String]
showPuzzle = map showRow
printPuzzle :: [[Maybe Int]] -> IO ()
printPuzzle = mapM_ putStrLn . showPuzzle
showRow takes a single row from your grid and prints it - using the maybe function from Data.Maybe, we can write this as a quick map from each Maybe Int value to either a default "blank space" value or the character representing the number (using intToDigit).
showPuzzle simply maps showRow over the outer list.
printPuzzle just uses the previous pure definitions to give the impure action which prints a grid, by putStrLn'ing the pretty-print of each row.
A quick demo:
> printPuzzle [[Just 1, Nothing, Just 3],
[Nothing, Just 3, Just 6],
[Just 2, Just 4, Just 5]]
1 3
36
245
Though you can easily modify the above code to print something more explicit, like:
1X3
X36
245
I have a RDD of this form:
org.apache.spark.rdd.RDD[(String, Int, Array[String])]
This is the first element of the RDD:
(001, 5, Array(a, b, c))
And I want to split that list on several columns, as it is separated by commas, the expected output would be:
(001, 5, a, b, c)
Any help?
SOLUTION:
I finally resolved the problem:
What I did was compose the array in a entire string with:
mkstring(",")
and then, converted the rdd to dataframe. With that, I was able to split the string in columns with the method withColumns
I think you just need to get values from the list one by one and put them into a tuple. Try this
val result = RDD.map(x => (x._1, x._2, x._3(0), x._3(1), x._3(2)))
If you have something like this,
RDD[(String, Int, List[String])]
In general you should not try to generate an RDD with elements of that List as columns.
The reason being the fact that Scala is a Strictly Typed language and your RDD[T] needs to be a RDD of type T.
Now lets say your RDD only had following two "rows" (elements) with lists of different lengths,
("001", 5, List("a", "b", "c"))
("002", 5, List("a", "b", "c", "d"))
Now as you can see... that the first row will need a RDD[(String, Int, String, String, String)] but the second will need a RDD[(String, Int, String, String, String, String)].
This will result in the generated RDD to think of its type as Any and you will have an RDD[Any]. And this Any type will further restrict you in doing things because of Erasure at run-time.
But the special case where, you can do this without problem is - if you know that each list has known and same length (lets say 3 in this case),
val yourRdd = rdd.map({
case (s, i, s1 :: s2 :: s3 :: _) => (s, i, s1, s2, s3)
})
Now... If it is not this special case and your lists can have different unknown sizes... and if even you want to do that... converting a list of unspecified length to tuple is not an easy thing to do. At least, I can not think of any easy way to do that.
And I will advise you to avoid trying to do that without a very very solid reason.
Suppose i have
Message = [{"from_email",From_Email},{"name",Name},{"text",Text}],
To=[{"to_email",ToMail},{"to_name",ToName}],
Send_Mail=[{"to",To},{"subject",Subject},{"message",Message},{"from_email",From_Email},{"from_name",From_Name}].
I want to convert Send_Mail into binary to parse into jason format. I am using jsx for parsing and jsx takes binary inputs.
A quick brute-force approach: iterate the list, recursively entering tuples and lists, converting all string-like lists to binary.
%% First exclude things that should be left alone:
list_to_jsx(E) when is_integer(E); is_float(E); is_atom(E); is_binary(E) -> E;
%% If converting a list, see if it can be made neatly into a
%% binary, if so, done, if not recurse into the list.
list_to_jsx(L) when is_list(L) ->
case catch list_to_binary(L) of
B when is_binary(B) -> B;
_ -> [convert(E) || E <- L]
end;
%% If converting a tuple, convert each element:
list_to_jsx(T) when is_tuple(T) ->
list_to_tuple([convert(E) || E <- tuple_to_list(T)]).
If you are confident that only 2-tuples appear in the input list, the last clause can be simplified slightly to
list_to_jsx({F,V}) -> {convert(F),convert(V)}.
JSX has encode functions to encode Erlang terms to JSON. But note that the keys should be atoms (from_email without quotes or in single quotes) or binaries (<<"from_email">>), not Erlang strings. If you are somehow stuck with the form you have, you can convert the keys (and values if necessary) into binaries with
[{list_to_binary(Key), if is_list(Value) -> list_to_binary(Value); true -> Value end} || {Key, Value} <- ListOfTuples]
If values can be JSON objects themselves, you'll need recursion. See Joe's answer for one approach.
To answer the more general question in the title:
If you just want to convert into a binary in some way and back, use erlang:term_to_binary. Works on any terms.
If you want to get a binary containing the string representation of the term, use erlang:iolist_to_binary(io_lib:write(Term)).
However, neither of these methods produce JSON.
I have a question about tuples and lists in Haskell. I know how to add input into a tuple a specific number of times. Now I want to add tuples into a list an unknown number of times; it's up to the user to decide how many tuples they want to add.
How do I add tuples into a list x number of times when I don't know X beforehand?
There's a lot of things you could possibly mean. For example, if you want a few copies of a single value, you can use replicate, defined in the Prelude:
replicate :: Int -> a -> [a]
replicate 0 x = []
replicate n | n < 0 = undefined
| otherwise = x : replicate (n-1) x
In ghci:
Prelude> replicate 4 ("Haskell", 2)
[("Haskell",2),("Haskell",2),("Haskell",2),("Haskell",2)]
Alternately, perhaps you actually want to do some IO to determine the list. Then a simple loop will do:
getListFromUser = do
putStrLn "keep going?"
s <- getLine
case s of
'y':_ -> do
putStrLn "enter a value"
v <- readLn
vs <- getListFromUser
return (v:vs)
_ -> return []
In ghci:
*Main> getListFromUser :: IO [(String, Int)]
keep going?
y
enter a value
("Haskell",2)
keep going?
y
enter a value
("Prolog",4)
keep going?
n
[("Haskell",2),("Prolog",4)]
Of course, this is a particularly crappy user interface -- I'm sure you can come up with a dozen ways to improve it! But the pattern, at least, should shine through: you can use values like [] and functions like : to construct lists. There are many, many other higher-level functions for constructing and manipulating lists, as well.
P.S. There's nothing particularly special about lists of tuples (as compared to lists of other things); the above functions display that by never mentioning them. =)
Sorry, you can't1. There are fundamental differences between tuples and lists:
A tuple always have a finite amount of elements, that is known at compile time. Tuples with different amounts of elements are actually different types.
List an have as many elements as they want. The amount of elements in a list doesn't need to be known at compile time.
A tuple can have elements of arbitrary types. Since the way you can use tuples always ensures that there is no type mismatch, this is safe.
On the other hand, all elements of a list have to have the same type. Haskell is a statically-typed language; that basically means that all types are known at compile time.
Because of these reasons, you can't. If it's not known, how many elements will fit into the tuple, you can't give it a type.
I guess that the input you get from your user is actually a string like "(1,2,3)". Try to make this directly a list, whithout making it a tuple before. You can use pattern matching for this, but here is a slightly sneaky approach. I just remove the opening and closing paranthesis from the string and replace them with brackets -- and voila it becomes a list.
tuplishToList :: String -> [Int]
tuplishToList str = read ('[' : tail (init str) ++ "]")
Edit
Sorry, I did not see your latest comment. What you try to do is not that difficult. I use these simple functions for my task:
words str splits str into a list of words that where separated by whitespace before. The output is a list of Strings. Caution: This only works if the string inside your tuple contains no whitespace. Implementing a better solution is left as an excercise to the reader.
map f lst applies f to each element of lst
read is a magic function that makes a a data type from a String. It only works if you know before, what the output is supposed to be. If you really want to understand how that works, consider implementing read for your specific usecase.
And here you go:
tuplish2List :: String -> [(String,Int)]
tuplish2List str = map read (words str)
1 As some others may point out, it may be possible using templates and other hacks, but I don't consider that a real solution.
When doing functional programming, it is often better to think about composition of operations instead of individual steps. So instead of thinking about it like adding tuples one at a time to a list, we can approach it by first dividing the input into a list of strings, and then converting each string into a tuple.
Assuming the tuples are written each on one line, we can split the input using lines, and then use read to parse each tuple. To make it work on the entire list, we use map.
main = do input <- getContents
let tuples = map read (lines input) :: [(String, Integer)]
print tuples
Let's try it.
$ runghc Tuples.hs
("Hello", 2)
("Haskell", 4)
Here, I press Ctrl+D to send EOF to the program, (or Ctrl+Z on Windows) and it prints the result.
[("Hello",2),("Haskell",4)]
If you want something more interactive, you will probably have to do your own recursion. See Daniel Wagner's answer for an example of that.
One simple solution to this would be to use a list comprehension, as so (done in GHCi):
Prelude> let fstMap tuplist = [fst x | x <- tuplist]
Prelude> fstMap [("String1",1),("String2",2),("String3",3)]
["String1","String2","String3"]
Prelude> :t fstMap
fstMap :: [(t, b)] -> [t]
This will work for an arbitrary number of tuples - as many as the user wants to use.
To use this in your code, you would just write:
fstMap :: Eq a => [(a,b)] -> [a]
fstMap tuplist = [fst x | x <- tuplist]
The example I gave is just one possible solution. As the name implies, of course, you can just write:
fstMap' :: Eq a => [(a,b)] -> [a]
fstMap' = map fst
This is an even simpler solution.
I'm guessing that, since this is for a class, and you've been studying Haskell for < 1 week, you don't actually need to do any input/output. That's a bit more advanced than you probably are, yet. So:
As others have said, map fst will take a list of tuples, of arbitrary length, and return the first elements. You say you know how to do that. Fine.
But how do the tuples get into the list in the first place? Well, if you have a list of tuples and want to add another, (:) does the trick. Like so:
oldList = [("first", 1), ("second", 2)]
newList = ("third", 2) : oldList
You can do that as many times as you like. And if you don't have a list of tuples yet, your list is [].
Does that do everything that you need? If not, what specifically is it missing?
Edit: With the corrected type:
Eq a => [(a, b)]
That's not the type of a function. It's the type of a list of tuples. Just have the user type yourFunctionName followed by [ ("String1", val1), ("String2", val2), ... ("LastString", lastVal)] at the prompt.
I have a question about tuples and lists in Haskell. I know how to add input into a tuple a specific number of times. Now I want to add tuples into a list an unknown number of times; it's up to the user to decide how many tuples they want to add.
How do I add tuples into a list x number of times when I don't know X beforehand?
There's a lot of things you could possibly mean. For example, if you want a few copies of a single value, you can use replicate, defined in the Prelude:
replicate :: Int -> a -> [a]
replicate 0 x = []
replicate n | n < 0 = undefined
| otherwise = x : replicate (n-1) x
In ghci:
Prelude> replicate 4 ("Haskell", 2)
[("Haskell",2),("Haskell",2),("Haskell",2),("Haskell",2)]
Alternately, perhaps you actually want to do some IO to determine the list. Then a simple loop will do:
getListFromUser = do
putStrLn "keep going?"
s <- getLine
case s of
'y':_ -> do
putStrLn "enter a value"
v <- readLn
vs <- getListFromUser
return (v:vs)
_ -> return []
In ghci:
*Main> getListFromUser :: IO [(String, Int)]
keep going?
y
enter a value
("Haskell",2)
keep going?
y
enter a value
("Prolog",4)
keep going?
n
[("Haskell",2),("Prolog",4)]
Of course, this is a particularly crappy user interface -- I'm sure you can come up with a dozen ways to improve it! But the pattern, at least, should shine through: you can use values like [] and functions like : to construct lists. There are many, many other higher-level functions for constructing and manipulating lists, as well.
P.S. There's nothing particularly special about lists of tuples (as compared to lists of other things); the above functions display that by never mentioning them. =)
Sorry, you can't1. There are fundamental differences between tuples and lists:
A tuple always have a finite amount of elements, that is known at compile time. Tuples with different amounts of elements are actually different types.
List an have as many elements as they want. The amount of elements in a list doesn't need to be known at compile time.
A tuple can have elements of arbitrary types. Since the way you can use tuples always ensures that there is no type mismatch, this is safe.
On the other hand, all elements of a list have to have the same type. Haskell is a statically-typed language; that basically means that all types are known at compile time.
Because of these reasons, you can't. If it's not known, how many elements will fit into the tuple, you can't give it a type.
I guess that the input you get from your user is actually a string like "(1,2,3)". Try to make this directly a list, whithout making it a tuple before. You can use pattern matching for this, but here is a slightly sneaky approach. I just remove the opening and closing paranthesis from the string and replace them with brackets -- and voila it becomes a list.
tuplishToList :: String -> [Int]
tuplishToList str = read ('[' : tail (init str) ++ "]")
Edit
Sorry, I did not see your latest comment. What you try to do is not that difficult. I use these simple functions for my task:
words str splits str into a list of words that where separated by whitespace before. The output is a list of Strings. Caution: This only works if the string inside your tuple contains no whitespace. Implementing a better solution is left as an excercise to the reader.
map f lst applies f to each element of lst
read is a magic function that makes a a data type from a String. It only works if you know before, what the output is supposed to be. If you really want to understand how that works, consider implementing read for your specific usecase.
And here you go:
tuplish2List :: String -> [(String,Int)]
tuplish2List str = map read (words str)
1 As some others may point out, it may be possible using templates and other hacks, but I don't consider that a real solution.
When doing functional programming, it is often better to think about composition of operations instead of individual steps. So instead of thinking about it like adding tuples one at a time to a list, we can approach it by first dividing the input into a list of strings, and then converting each string into a tuple.
Assuming the tuples are written each on one line, we can split the input using lines, and then use read to parse each tuple. To make it work on the entire list, we use map.
main = do input <- getContents
let tuples = map read (lines input) :: [(String, Integer)]
print tuples
Let's try it.
$ runghc Tuples.hs
("Hello", 2)
("Haskell", 4)
Here, I press Ctrl+D to send EOF to the program, (or Ctrl+Z on Windows) and it prints the result.
[("Hello",2),("Haskell",4)]
If you want something more interactive, you will probably have to do your own recursion. See Daniel Wagner's answer for an example of that.
One simple solution to this would be to use a list comprehension, as so (done in GHCi):
Prelude> let fstMap tuplist = [fst x | x <- tuplist]
Prelude> fstMap [("String1",1),("String2",2),("String3",3)]
["String1","String2","String3"]
Prelude> :t fstMap
fstMap :: [(t, b)] -> [t]
This will work for an arbitrary number of tuples - as many as the user wants to use.
To use this in your code, you would just write:
fstMap :: Eq a => [(a,b)] -> [a]
fstMap tuplist = [fst x | x <- tuplist]
The example I gave is just one possible solution. As the name implies, of course, you can just write:
fstMap' :: Eq a => [(a,b)] -> [a]
fstMap' = map fst
This is an even simpler solution.
I'm guessing that, since this is for a class, and you've been studying Haskell for < 1 week, you don't actually need to do any input/output. That's a bit more advanced than you probably are, yet. So:
As others have said, map fst will take a list of tuples, of arbitrary length, and return the first elements. You say you know how to do that. Fine.
But how do the tuples get into the list in the first place? Well, if you have a list of tuples and want to add another, (:) does the trick. Like so:
oldList = [("first", 1), ("second", 2)]
newList = ("third", 2) : oldList
You can do that as many times as you like. And if you don't have a list of tuples yet, your list is [].
Does that do everything that you need? If not, what specifically is it missing?
Edit: With the corrected type:
Eq a => [(a, b)]
That's not the type of a function. It's the type of a list of tuples. Just have the user type yourFunctionName followed by [ ("String1", val1), ("String2", val2), ... ("LastString", lastVal)] at the prompt.