Haskell: Tail of a String "a" - string

Why is the tail of a String with only one letter the empty String and not the empty List?
Example:
tail "a"
= ""
But you can create a String as:
'a' : []
= "a"
So I thought the tail should be the empty List [].
And if you do for example
tail ["x"]
then you get the empty List [].
This is a bit confusing.

Because the empty string is the empty list of Chars, it's just shown differently:
Prelude> [] :: String
""

It's because the empty String and empty list of Char are the exact same thing (type String = [Char]). The Show instance for Char takes this into account and overrides the list rendering (using showList) to render as strings. This is why there's no Show instance for String; Show a => Show [a] handles all lists and uses showList [Char].
As an aside, text is a lot more complex than just a string of characters. That approximation was chosen early on in C and Haskell, but other implementations like Data.Text may have better approaches.

When you define an instance of the Show type class you can implement the method showList, which is the way list of that type are display. So:
showList [] = "" -- I guess this is not the actual implementation, but something similar
Regards,

Related

Haskell recursive program

I begin the function from here and don't know what to do next. Please help me in solving this function.
Write a Haskell recursive function noDupl which returns True if there
are no duplicates characters in the given string.
noDupl :: String -> Bool
noDupl = ?
Example Output:
noDupl "abcde"
True
noDupl "aabcdee"
False
Well, you've got the type signature right. Now like all recursion questions you can then think about the base case (where the recursion ends) and the recursive case (which will recurse with a smaller input).
For strings (and lists in general), the base case is usually the empty string (list). The recursive case usually takes the head of the list, processes it, then pushes to the front of the new result.
This probably sounds pretty confusing. It'll make sense when you look at some examples:
-- Increment each character by one (by ASCII).
incAll :: String -> String
incAll [] = [] -- Base case: empty string (list).
incAll (x:xs) = chr (ord x + 1) : incAll xs -- Recursive case, process head and prepend to recursed result.
There's a more concise way to write the above, but it demonstrates how recursion could be done.
Of course, you don't have to process each char individually, you could pattern match on two chars like so:
f (x0:x1:xs) = ...
(But you'll need to be careful with the base case.)
Hopefully this provides you with enough hints to write noDupl.

How to convert a string to an array containing each character in Haskell?

I was looking at this post here:
Haskell get character array from string?
I see it says that in haskell strings are essentially arrays containing each letter, but I was wondering; how would I turn the format from the string to an array of individual components, for example:
["ABCD","EFGH"]
to
[["A","B","C","D"],["E","F","G","H"]]
I'd like to know a method without using any external imports.
You can wrap each element in a singleton list, so:
map (map pure) ["ABCD", "EFGH"] :: [[String]]
this then produces:
Prelude> map (map pure) ["ABCD", "EFGH"] :: [[String]]
[["A","B","C","D"],["E","F","G","H"]]
That being said, a String is simply a list of Chars, indeed:
type String = [Char]
so if you just want to work with a list of Chars, you can simply work with the string directly. By converting it to a list of list of Strings, we know that all these strings contain one Char, but that is no longer guaranteed by the type.

converting a list of string into a list of tuples in Haskell

I have a list of strings:
[" ix = index"," ctr = counter"," tbl = table"]
and I want to create a tuple from it like:
[("ix","index"),("ctr","counter"),("tbl","table")]
I even tried:
genTuple [] = []
genTuples (a:as)= do
i<-splitOn '=' a
genTuples as
return i
Any help would be appriciated
Thank you.
Haskell's type system is really expressive, so I suggest to think about the problem in terms of types. The advantage of this is that you can solve the problem 'top-down' and the whole program can be typechecked as you go, so you can catch all kinds of errors early on. The general approach is to incrementally divide the problem into smaller functions, each of which remaining undefined initially but with some plausible type.
What you want is a function (let's call it convert) which take a list of strings and generates a list of tuples, i.e.
convert :: [String] -> [(String, String)]
convert = undefined
It's clear that each string in the input list will need to be parsed into a 2-tuple of strings. However, it's possible that the parsing can fail - the sheer type String makes no guarantees that your input string is well formed. So your parse function maybe returns a tuple. We get:
parse :: String -> Maybe (String, String)
parse = undefined
We can immediately plug this into our convert function using mapMaybe:
convert :: [String] -> [(String, String)]
convert list = mapMaybe parse list
So far, so good - but parse is literally still undefined. Let's say that it should first verify that the input string is 'valid', and if it is - it splits it. So we'll need
valid :: String -> Bool
valid = undefined
split :: String -> (String, String)
split = undefined
Now we can define parse:
parse :: String -> Maybe (String, String)
parse s | valid s = Just (split s)
| otherwise = Nothing
What makes a string valid? Let's say it has to contain a = sign:
valid :: String -> Bool
valid s = '=' `elem` s
For splitting, we'll take all the characters up to the first = for the first tuple element, and the rest for the second. However, you probably want to trim leading/trailing whitespace as well, so we'll need another function. For now, let's make it a no-op
trim :: String -> String
trim = id
Using this, we can finally define
split :: String -> (String, String)
split s = (trim a, trim (tail b))
where
(a, b) = span (/= '=') s
Note that we can safely call tail here because we know that b is never empty because there's always a separator (that's what valid verified). Type-wise, it would've been nice to express this guarantee using a "non-empty string" but that may be a bit overengineered. :-)
Now, there are a lot of solutions to the problem, this is just one example (and there are ways to shorten the code using eta reduction or existing libraries). The main point I'm trying to get across is that Haskell's type system allows you to approach the problem in a way which is directed by types, which means the compiler helps you fleshing out a solution from the very beginning.
You can do it like this:
import Control.Monda
import Data.List
import Data.List.Split
map ((\[a,b] -> (a,b)) . splitOn "=" . filter (/=' ')) [" ix = index"," ctr = counter"," tbl = table"]

Find and replace in Haskell

I want to input a list of 2 element lists of characters (just letters) where the first element is a letter in a String (the second argument for findAndReplace) and the second is what I want it changed to. Is there already a function in Haskell that does a similar thing? Because this would help greatly!
It sounds more like you might want to use a list of tuples instead of a list of lists for your first input, since you specify a fixed length. Tuples are fixed-length collections that can have mixed types, while lists are arbitrary-length collections of a single type:
myTuple = ('a', 'b') :: (Char, Char)
myTriple = ('a', 'b', 'c') :: (Char, Char, Char)
myList = ['a'..'z'] :: [Char]
Notice how I have to specify the type of each field of the tuples. Also, (Char, Char) is not the same type as (Char, Char, Char), they are not compatible.
So, with tuples, you can have your type signature for replace as:
replace :: [(Char, Char)] -> String -> String
And now this specifies with the type signature that it has to be a list of pairs of characters to find and replace, you won't have to deal with bad input, like if someone only gave a character to search for but not one to replace it with.
We now are passing in what is commonly referred to as an association list, and Haskell even has some built in functions for dealing with them in Data.List and Data.Map. However, for this exercise I don't think we'll need it.
Right now you're wanting to solve this problem using a list of pairs, but it'd be easier if we solved it using just one pair:
replace1 :: (Char, Char) -> String -> String
replace1 (findChr, replaceChr) text = ?
Now, you want to check each character of text and if it's equal to findChr, you want to replace it with replaceChr, otherwise leave it alone.
replace1 (findChr, replaceChr) text = map (\c -> ...) text
I'll let you fill in the details (hint: if-then-else).
Then, you can use this to build your replace function using the simpler replace1 function. This should get you started, and if you still can't figure it out after a day or two, comment below and I'll give you another hint.

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)

Resources