Haskell - how to convert [1,2,3] to "123" - haskell

How do I convert a list of integers [1,2,3] to a string "123"
Sorry for asking the obvious, but I don't seem to be able to find the answer elsewhere.

The best way would be to use show and concatMap, which is just a combination of concat and map:
> concatMap show [1, 2, 3]
"123"
This also works for numbers with more than one digit:
> concatMap show [10, 20, 30]
"102030"
Since type String = [Char], we can just treat this as a list processing problem The first part is to convert each number to its String representation, which is done simply using show. Since we want to apply this to a list of numbers, map is the tool of choice. Finally, we want to join all the string representations (list of Char representations) into a single string (list of Char), so concat is appropriate:
> concat $ map show [1, 2, 3]
"123"
Whenever you see concat $ map f some_list, you can always use the pre-defined tool concatMap, since this is precisely its definition:
> concatMap show [1, 2, 3]
"123"
As pointed out in the comments, you can use foldMap from the Data.Foldable module that generalizes the whole "map then combine" functionality. The Foldable typeclass basically just means that you can use folds on it, and it also uses Monoid, which basically just means you have a way to combine two elements, such as concatenation for lists or addition for numbers. Alternatively, you can also use the fact that lists form a Monad and use the >>= operator as
> [1, 2, 3] >>= show
"123"
In the end, all of these operations pretty much boil down to applying a function to each element, then combining those results together using some other function. It's a very general pattern and can be applied in a lot of cases, hence why there's generalizations of it.

Alternatively, you could use
map (chr . (ord '0' +)) [1,2,3,4]
if all of your integers are single digits (you would need to import chr and ord from Data.Char).
This works because String is just a type synonym of [Char] in Haskell, so all we are doing is just mapping each Int in your list to the appropriate Char.

Related

How to read a list from stdin of arbitrary type [a] in Haskell?

I'm writing a function that takes arbitrary lists and compares them to see if one is a sublist of the other. For stdin, I wanted to ask the user for two lists but I can't figure out a way to accept an arbitrary type. Here is my code so far:
1 main :: IO ()
2 main = do
3 l1 <- getLine
4 l2 <- getLine
5 print $ sublist (read l1 :: [Int]) (read l2:: [Int])
6
7 sublist :: Eq a => [a] -> [a] -> Bool
8 sublist b p = any ((b ==) . take len) . takeWhile ((len<=) . length) $ iterate tail p
9 where len = length b
My main issue is line 5 where I have to pick a type for read.
Some examples of input and output I would want to have while I can only currently support one at a time:
>>> [1,2,3]
[1,2,3,4,5]
True
>>> ["a", "bc"]
["xy", "b", "bc"]
False
>>> [True, False, True]
>>> [False, True, False, True]
True
-- And even nested types
>>> [[1], [2,3]]
[[2,4], [1], [2,3], [4]
True
Any help would be greatly appreciated!
read has to know in advance what kind of thing it is reading - that's just the way it works.
It is not the case that read looks at the string to determine what type to return. For instance consider:
read "1" :: Float
read "1" :: Int
The first read will return a Float (1.0) and the second an Int (1) even though the string being read is exactly the same.
You might think this is different from other languages, such as Python, where you can eval "[1,2,3]" and get a list and eval "5" to get a number and you don't have to tell eval what kind of thing to return. However, Haskell's answer to that is those languages are really only dealing with one type which is a sum type like:
data PyVal = PyNum Int
| PyStr String
| PyList [ PyVal ]
| PyDict [ (PyStr, PyVal) ]
| ...
Hence the universe of possible expressions is closed. So, actually, eval knows what kind of thing it is reading. In Haskell you can always add new types and therefore new reader and show functions.
Your fundamental problem is Haskell-independent. Simply giving someone two string representations of values is not enough to determine equality. You have to tell that person what the interpretation of those values is supposed to be since one string can be interpreted many ways.
For example, let's say I give you the following inputs
>>> ['a', 'b']
['A', 'B']
What should you return? If I mean this to be interpreted using standard case-sensitive characters, then I should get back False. If on the other hand I'm using case-insensitive characters (e.g. as provided by this package) then I should get back True. Just giving me the string representations is ambiguous.
If what you care about is the string representation itself, then just read your values into lists of strings and use sublist on those. If you do care about the interpretation of that string, then you have to either allow the user to specify that interpretation, or specify that interpretation in code somehow (of which #ErikR's ADT encoding and your type annotations are two possibilities).

How to access nth element in a Haskell tuple

I have this:
get3th (_,_,a,_,_,_) = a
which works fine in GHCI but I want to compile it with GHC and it gives error. If I want to write a function to get the nth element of a tuple and be able to run in GHC what should I do?
my all program is like below, what should I do with that?
get3th (_,_,a,_,_,_) = a
main = do
mytuple <- getLine
print $ get3th mytuple
Your problem is that getLine gives you a String, but you want a tuple of some kind. You can fix your problem by converting the String to a tuple – for example by using the built-in read function. The third line here tries to parse the String into a six-tuple of Ints.
main = do
mystring <- getLine
let mytuple = read mystring :: (Int, Int, Int, Int, Int, Int)
print $ get3th mytuple
Note however that while this is useful for learning about types and such, you should never write this kind of code in practise. There are at least two warning signs:
You have a tuple with more than three or so elements. Such a tuple is very rarely needed and can often be replaced by a list, a vector or a custom data type. Tuples are rarely used more than temporarily to bring two kinds of data into one value. If you start using tuples often, think about whether or not you can create your own data type instead.
Using read to read a structure is not a good idea. read will explode your program with a terrible error message at any tiny little mistake, and that's usually not what you want. If you need to parse structures, it's a good idea to use a real parser. read can be enough for simple integers and such, but no more than that.
The type of getLine is IO String, so your program won't type check because you are supplying a String instead of a tuple.
Your program will work if proper parameter is supplied, i.e:
main = do
print $ get3th (1, 2, 3, 4, 5, 6)
It seems to me that your confusion is between tuples and lists. That is an understandable confusion when you first meet Haskell as many other languages only have one similar construct. Tuples use round parens: (1,2). A tuple with n values in it is a type, and each value can be a different type which results in a different tuple type. So (Int, Int) is a different type from (Int, Float), both are two tuples. There are some functions in the prelude which are polymorphic over two tuples, ie fst :: (a,b) -> a which takes the first element. fst is easy to define using pattern matching like your own function:
fst (a,b) = a
Note that fst (1,2) evaluates to 1, but fst (1,2,3) is ill-typed and won't compile.
Now, lists on the other hand, can be of any length, including zero, and still be the same type; but each element must be of the same type. Lists use square brackets: [1,2,3]. The type for a list with elements of type a is written [a]. Lists are constructed from appending values onto the empty list [], so a list with one element can be typed [a], but this is syntactic sugar for a:[], where : is the cons operator which appends a value to the head of the list. Like tuples can be pattern matched, you can use the empty list and the cons operator to pattern match:
head :: [a] -> a
head (x:xs) = x
The pattern match means x is of type a and xs is of type [a], and it is the former we want for head. (This is a prelude function and there is an analogous function tail.)
Note that head is a partial function as we cannot define what it does in the case of the empty list. Calling it on an empty list will result in a runtime error as you can check for yourself in GHCi. A safer option is to use the Maybe type.
safeHead :: [a] -> Maybe a
safeHead (x:xs) = Just x
safeHead [] = Nothing
String in Haskell is simply a synonym for [Char]. So all of these list functions can be used on strings, and getLine returns a String.
Now, in your case you want the 3rd element. There are a couple of ways you could do this, you could call tail a few times then call head, or you could pattern match like (a:b:c:xs). But there is another utility function in the prelude, (!!) which gets the nth element. (Writing this function is a very good beginner exercise). So your program can be written
main = do
myString <- getLine
print $ myString !! 2 --zero indexed
Testing gives
Prelude> main
test
's'
So remember, tuples us ()and are strictly of a given length, but can have members of different types; whereas lists use '[]', can be any length, but each element must be the same type. And Strings are really lists of characters.
EDIT
As an aside, I thought I'd mention that there is a neater way of writing this main function if you are interested.
main = getLine >>= print . (!!3)

Haskell - defining functions

I am new to programming and to Haskell. I'm having trouble understanding how to define a function. Let's say I want a function that will return element in position a of a list [b]. For a specific a and [b] I can do this in the interpreter:
Prelude> [2, 3, 5, 6] !! 1
Prelude> 3
But I run into trouble if I try to make a function, either in the interpreter or in a text editor that is then loaded:
Prelude> let getElement a [b] = [b] !! a
Prelude> getElement 1 [2, 3, 5, 6]
***Exception: <interactive>:17:5-27: Non-exhaustive pattern in function getElement
let getElement a [b] = [b] !! a
Your function takes one argument a of type Int, since (!!) second parameter is an Int, and [b] pattern matches on a list with one element.
It looks like you were trying to tell the complier that the second parameter should be a list. To do this you normally use the type signature.
In a file:
getElement :: Int -> [b] -> b
getElement a bs = bs !! a
This type of function is considered partial since you can give it an integer that causes the function to fail and throw an exception, such as a negative number or trying to access an index larger then the list. This chapter in real world Haskell has some information on partial function. The Haskell wiki in on the programming guidelines page has some advise too.
You may want to look at the
safe package and how they define headMay for a total, rather then partial, implementation.
Edit: b changed to bs as recommend by Rein Henrichs below, as he points out it does make it easier to read and is a rather common idiom.

A list of list or a tuple of tuples

I was just wondering if there is a possibility to create a function that returns an (hopefully infinite) list of numbers similar to this. [1, [2, [3, [4]]]].
The closest I got was this.
func list 0 = list
func list num = func newList (num-1)
where newList = list ++ [[num]]
This is used something like this.
func [] 3
Which returns this.
[[3],[2],[1]]
Now I know that this is not infinite nor is it in the correct order but I just wanted to show that I was at least attempting something before posting. :)
Thanks a bunch!
You cannot write such a function, because all elements of a list must have the same type. The list you want to create would not typecheck even in the case of just two elements:
Prelude> :t [1::Int,[2::Int]]
<interactive>:1:9:
Couldn't match expected type `Int' with actual type `[Int]'
In the expression: [2 :: Int]
In the expression: [1 :: Int, [2 :: Int]]
First element is a Int, second one a list of Int, hence typechecking fails.
Although you can express the result with tuples, e.g.
Prelude> :t (1::Int,(2::Int,(3::Int,4::Int)))
(1::Int,(2::Int,(3::Int,4::Int))) :: (Int, (Int, (Int, Int)))
You still cannot write the function, because the type of the result would change depending on the number of elements you wish to have. Let's call f the hypothetical function:
f 1 :: (Int)
f 2 :: (Int,(Int))
f 3 :: (Int,(Int,(Int)))
...
The type of f changes with the argument, so f cannot be written.
The key is to come up with the correct type.
If you want something like [1, [2, [3, [4]]]], then doing exactly that won't work, because all list elements must be the same type.
This makes sense, because when I grab an element out of the list, I need to know what type it is before I can do anything with it (this is sort of the whole point of types, they tell you what you can and can't do with a thing).
But since Haskell's type system is static, I need to know what type it is even without knowing which element of the list it is, because which list index I'm grabbing might not be known until the program runs. So I pretty much have to get the same type of thing whatever index I use.
However, it's possible to do something very much like what you want: you want a data type that might be an integer, or might be a list:
type IntegerOrList a = Either Integer [a]
If you're not familiar with the Either type, a value of Either l r can either be Left x for some x :: l, or Right y for some y :: r. So IntegerOrList a is a type whose values are either an integer or a list of something. So we can make a list of those things: the following is a value of type [IntegerOrList Bool]:
[Left 7, Left 4, Right [True, False], Left 8, Right [], Right [False]]
Okay, so that's one level of lists inside lists, but we can't put lists inside lists inside lists yet – the inner lists contain Bools, which can't be lists. If we instead had [IntegerOrList (IntegerOrList Bool)], we'd be able to have lists inside lists inside lists, but we'd still get no further. In our example, we had a list which contained values which were either integers or lists, and the lists were lists which contained values which were either integers or lists, and... what we really want is something like IntegerOrList (IntegerOrList (IntegerOrList ..., or more simply, something like:
type IntegerOrLists = Either Integer [IntegerOrLists]
But that's not allowed – type synonyms can't be recursive, because that would produce an infinitely large type, which is confusing for the poor compiler. However, proper data types can be recursive:
data IntegerOrLists = I Integer | L [IntegerOrLists]
Now you can build lists like these, mixing integers and lists of your type:
L [I 1, L [I 2, L [I 3, L [I 4]]]]
The key is that whether each item is an integer or a list has to be flagged by using the I or L constructors. Now each element of the list is of type IntegerOrLists, and we can distinguish which it is by looking at that constructor. So the typechecker is happy at last.
{-# LANGUAGE ExistentialQuantification #-}
class Foo a
instance Foo Int
instance Foo [a]
data F = forall a. Foo a => F a
test = F [F (1 :: Int), F [F (2 :: Int), F [F (3 :: Int), F [F (4 :: Int)]]]]
This example shows
That you can have such structures in Haskell, just use some gift wrapping
That these structures are practically useless (try to do something with it)

How do I convert a list to a tuple in Haskell?

How can I best convert a list to a tuple in Haskell:
[1,2,3,4,5,6] -> (1,2,3,4,5,6)
In a general way, you can't. Each size of tuple is a distinct type, whereas lists of any length are a single type. Thus, there's no good way to write a function that takes a list and returns a tuple of the same length--it wouldn't have a well-defined return type.
For instance, you could have functions like:
tuplify2 :: [a] -> (a,a)
tuplify2 [x,y] = (x,y)
tuplify3 :: [a] -> (a,a,a)
tuplify3 [x,y,z] = (x,y,z)
...but not one that does the job of both.
You can write a generic version using various kinds of meta-programming, but you'd rarely want to.
Note that the same problem applies to other things, such as writing class instances for various tuples--take a look at the source code for Data.Tuple from the standard libraries!
Template Haskell is as close as you can get due to type checking if you want to extract a variable number of elements, since (a,b) and (a,b,c) have different types.
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
tuple :: Int -> ExpQ
tuple n = do
ns <- replicateM n (newName "x")
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)
Then:
$(tuple 6) [1,2,3,4,5,6] == (1,2,3,4,5,6)
$(tuple 3) "abc" == ('a','b','c')
But in general, if you need this answer, then you're asking the wrong question somewhere.
If you just want flat random access, perhaps the better option would be to use an Array.
If feel like I am about to advise you to point a gun at your foot and trust you not to shoot.
> list2Tuple lst = read $ "(" ++ (init.tail.show) lst ++ ")"
> list2Tuple [1,2,3] :: (Int, Int, Int)
(1,2,3)
> list2Tuple [1,2,3,4] :: (Int, Int, Int, Int)
(1,2,3,4)
This will work up to the what ever length of tuple Show and Read are defined for.
Tuples and lists are very different things. About the best you can do is to manually write a conversion function:
toTuple :: [a] -> (a,a,a,a,a,a)
toTuple [a,b,c,d,e,f] = (a,b,c,d,e,f)
Notice how different the types are: the single variable of the list expands to six variables for the tuple. So you'll need one function for each size of tuple.
I find it difficult to make cogent explanations of Template Haskell manipulations, but here is a demonstration:
> :m +Language.Haskell.TH
> :set -XTemplateHaskell
> runQ [| [1,2,3,4,5,6] |] >>= putStrLn . pprint
[1, 2, 3, 4, 5, 6]
> runQ [| [1,2,3,4,5,6] |] >>= \ (ListE exps) -> putStrLn (pprint (TupE exps))
(1, 2, 3, 4, 5, 6)
I don't think it's possible to do this in Haskell, for a list of arbitrary length not known at compile time. Template Haskell can't do it because it operates only at compile time. I ran into a case where I needed to do precisely this, and I had to work around it. A database library expects different-length tuples for query arguments, but I have an arbitrary-length list. So I have to skirt around the library interface. It would be nice if it could take a list.
Basically the issue is that different-length tuples are different types. But the Haskell compiler has to know at compile type what types might exist at runtime. Converting an arbitrary-length list into a tuple at run time could create some type it didn't know about at compile time.
You can in fact do better than manually writing one function per tuple-size if you use quasi-quotation as explained here. However, I would wonder about code where you expect to use this generically.
When dealing with command line arguments you can use getArgs, that function will give you a list with strings:
getArgs :: IO [String]
Link: https://hackage.haskell.org/package/base-4.16.0.0/docs/System-Environment.html#v:getArgs
When I work with command line arguments I prefer to work with tuples instead of a list, so I convert the list to a tuple. See below:
import System.Environment
main = do
args <- getArgs
let (a:b:c) = args
print a
Calling the program (in PowerShell):
PS C:\Haskell> runghc convertListToTuple goodday to you
"goodday"

Resources