Check if tuple or triple in haskell - haskell

Is there a way to check how many elements (,) has? I know I can access first and second element of a tuple with fst and snd but and thought I could somehow sum elements and then compare it with fst tuple snd tuple and check like this:
tuple = (1,2)
sum tuple == fst tuple + snd tuple
and then I get True for this case and get False for triple = (1,2,3). Eitherway I cant ask fst (1,2,3) nor I can do sum tuple
Is there a way to check if I have a tuple or not?
Something like this:
is_tuple :: (a,b) -> a
is_tuple (a,_) = a
but to get True when I input tuple and False when I give (1,2,3) or (1,2,3,4) and so on... as a input.
i.e:
is_tuple :: Tuple -> Bool
is_tuple x = if x is Tuple
then True
else False
?

Is there a way to check how many elements (,) has?
No, because the answer is always 2.
The type (,) is the type constructor for a tuple of two values, or a 2-tuple. It is a distinct type from (,,), the constructor for 3-tuples. Likewise, both those types are distinct from (,,,), the constructor for 4-tuples, and so on.
When you write a function with type (Foo, Bar) -> Baz, the typechecker will reject any attempts to call the function with a tuple of a different number of values (or something that isn’t a tuple at all). Therefore, your isTuple function only has one logical implementation,
isTuple :: (a, b) -> Bool
isTuple _ = True
…since it is impossible to ever actually call isTuple with a value that is not a 2-tuple.
Without using typeclasses, it is impossible in Haskell to write a function that accepts a tuple of arbitrary size; that is, you cannot be polymorphic over the size of a tuple. This is because, unlike lists, tuples are heterogenous—they can contain values of different types. A function that accepts a tuple of varying length would have no way to predict which elements of the tuple are of which type, and therefore it wouldn’t be able to actually do anything useful.
Very rarely, when doing advanced, type-level trickery, it can be useful to have a type that represents a tuple of varying length, which in Haskell is frequently known as an HList (for heterogenous list). These can be implemented as a library using fancy typeclass machinery and type-level programming. However, if you are a beginner, this is definitely not what you want.
It is difficult to actually give advice on what you should do because, as a commenter points out, your question reads like an XY problem. Consider asking a different question that gives a little more context about the problem you were actually trying to solve that made you want to find the list of a tuple in the first place, and you’ll most likely get more helpful answers.

Related

Manipulating Tuples in Haskell

I'm new to Haskell, I have a question regarding tuples. Is there not a way to traverse a tuple? I understand that traversal is very easy with lists but if the input is given as a tuple is there not a way to check the entire tuple as you do with a list? If that's not the case would it possible to just extract the values from the tuple into a list and perform traversal that way?
In Haskell, it’s not considered idiomatic (nor is it really possible) to use the tuple as a general-purpose traversable container. Any tuple you deal with is going to have a fixed number of elements, with the types of these elements also being fixed. (This is quite different from how tuples are idiomatically used in, for example, Python.) You ask about a situation where “the input is given as a tuple” but if the input is going to have a flexible number of elements then it definitely won’t be given as a tuple—a list is a much more likely choice.
This makes tuples seem less flexible than in some other languages. The upside is that you can examine them using pattern matching. For example, if you want to evaluate some predicate for each element of a tuple and return True if the predicate passes for all of them, you would write something like
all2 :: (a -> Bool) -> (a, a) -> Bool
all2 predicate (x, y) = predicate x && predicate y
Or, for three-element tuples,
all3 :: (a -> Bool) -> (a, a, a) -> Bool
all3 predicate (x, y, z) = predicate x && predicate y && predicate z
You might be thinking, “Wait, you need a separate function for each tuple size?!” Yes, you do, and you can start to see why there’s not a lot of overlap between the use cases for tuples and the use cases for lists. The advantages of tuples are exactly that they are kind of inflexible: you always know how many values they contain, and what type those values have. The former is not really true for lists.
Is there not a way to traverse a tuple?
As far as I know, there’s no built-in way to do this. It would be easy enough to write down instructions for traversing a 2-tuple, traversing a 3-tuple, and so on, but this would have the big limitation that you’d only be able to deal with tuples whose elements all have the same type.
Think about the map function as a simple example. You can apply map to a list of type [a] as long as you have a function a -> b. In this case map looks at each a value in turn, passes it to the function, and assembles the list of resulting b values. But with a tuple, you might have three elements whose values are all different types. Your function for converting as to bs isn’t sufficient if the tuple consists of two a values and a c! If you try to start writing down the Foldable instance or the Traversable instance even just for two-element tuples, you quickly realize that those typeclasses aren’t designed to handle containers whose values might have different types.
Would it be possible to just extract the values from the tuple into a list?
Yes, but you would need a separate function for each possible size of the input tuple. For example,
tupleToList2 :: (a, a) -> [a]
tupleToList2 (x, y) = [x, y]
tupleToList3 :: (a, a, a) -> [a]
tupleToList3 (x, y, z) = [x, y, z]
The good news, of course, is that you’re never going to get a situation where you have to deal with tuples of arbitrary size, because that isn’t a thing that can happen in Haskell. Think about the type signature of a function that accepted a tuple of any size: how could you write that?
In any situation where you’re accepting a tuple as input, it’s probably not necessary to convert the tuple to a list first, because the pattern-matching syntax means that you can just address each element of the tuple individually—and you always know exactly how many such elements there are going to be.
If your tuple is a homogeneous tuple, and you don't mind to use the third-party package, then lens provides some functions to traverse each elements in an arbitrary tuple.
ghci> :m +Control.Lens
ghci> over each (*10) (1, 2, 3, 4, 5) --traverse each element
(10,20,30,40,50)
Control.Lens.Tuple provides some lens to get and set the nth element up to 19th.
You can explore the lens package for more information. If you want to learn the lens package, Optics by examples by Chris Penner is a good book.

Convert a list to list with type-constrained fixed length

Let I define a list with constrained length. I.e.
data List (n::Nat) a where
Nil :: List 0 a
Cons :: a -> List (n-1) a -> List n a
Then I want to initialize this list from common list (e.g. input string with any length). Can I do that? Is it possible to write function (or class) like this?
toConsList :: [a] -> List n a
Or is this suitable only for a structures with length which is known in compile time?
You can't, because that would require dependent types. The type of the resulting List depends on the value. As your type error shows, you can't use foldr Cons Nil (which would be the obvious implementation) to create the list because the accumulator must stay the same type for the entire fold.
As #chi pointed out in the comments, you can use an existential wrapper to ignore the type parameter to allow this to work. You would end up with a value that was List n a for some unknown n, which gains you nothing over just using [a].
There is Data.Vector.Fixed.fromList, but the documentation there tells us that it "Will throw error if list is shorter than resulting vector." This means that it is really just asking you to specify the type (length) of your vector (list) at compile time, and truncating or throwing an error at runtime if that expectation is not met.
You may be interested in Idris' Data.Vect.Vect.

Syntax for List Patterns in Function Declaration

I'm learning haskell and have been writing various fairly trivial functions to get a handle on the language. I wrote this function:
doubleOneOrTail :: [t]->[t]
doubleOneOrTail [x] = [x,x]
doubleOneOrTail (x:xs) = xs
Which does exactly what is says. Doubles the list of 1 element, or returns the tail of a list of multiple elements. This generic syntax will work for a list of single elements or list of lists, etc. I can rewrite this function to the following:
doubleOneOrTail :: [[t]]->[[t]]
doubleOneOrTail [[x]] = [[x,x]]
doubleOneOrTail (x:xs) = xs
This will throw an error if I type the following:
doubleOneOrTail [1,2,3]
but it does accept this:
doubleOneOrTail [[[[1,2,3],[2]]]]
Treats it as a list with a single element (that element being a list of lists) and doubles it.
Clearly the pattern [a]->[a] isn't matching a list of single elements but in some way matching any order of lists. Whlie [[a]]->[[a]] is also matching multiple orders of lists (though not lists of just single elements). If anyone could explain how this is working it would be greatly appreciated.
A secondary question is it possible (or even desirable) to have a function declaration that specifically takes a particular order of a list. Say only lists of lists?
It sounds like you have a pretty good understanding of what's surprising you here: [a] is a list of any type of thing at all, including a list of lists. You can work out by hand what the type inferencer does automatically. Suppose that, using your first definition, we write:
let xs = [[[1,2], [3,4]], [[5]]]
in doubleOneOrTail xs
At this point GHC has to make sure the types match up for us.
xs :: [[[Integer]]] -- really could be any Num type, but assume Integer
Now since we're calling doubleOneOrTail with an [[[Integer]]] as argument, GHC must unify the types [a] and [[[Integer]]], which means finding some concrete type to substitute for a that makes the two types match up. There is only one correct answer:
[a] ~ [[[Integer]]]
a ~ [[Integer]]
Therefore, we are doubling or tailing a list of things, where each thing is a list of list of numbers. And since the types do indeed unify, GHC gives the all-clear, the function call compiles, and as a result we get [[[5]]].
As to your second question, whether you could or should restrict to a particular depth of lists: usually you should not. This kind of function is called parametrically polymorphic, meaning it works for any kind of a at all, no matter what it is; this is a useful property that it's good to preserve when possible. If your function doesn't need to look at values of its a type in order to perform correctly, it should allow them to be of any type.
Suppose that you still wanted to restrict its type? I don't know of a way to restrict it to depth-one lists without also adding some other incidental restriction. For example, you could say that it must be a list of numbers (and hope that nobody defines a Num instance for lists!):
doubleOneOrTail :: Num a => [a] -> [a]
Or you could limit it to a very specific type, such as [Int]. This would guarantee it can only ever be called with that type.
doubleOneOrTail :: [Int] -> [Int]
But as discussed above, all of these approaches unnecessarily restrict the type of your function. Better to define it as generally as possible, and find some other way to satisfy whatever other concerns make you want to restrict its type.
Little addition to #amalloy answer. Most probably you'll be fine with Enum class constraint:
doupbleOneOrTrail :: (Enum t) => [t] -> [t]
So your function accepts list of chars, numbers, booleans, etc
λ: doubleOneOrTail "foo"
"oo"
λ: doubleOneOrTail [False]
[False,False]

dealing with tuple of list with flexible size in haskell

I am learning Haskell, this question may be very stupid, but sorry I don't know its answer
I have a function that take a 4-tuple of list, size of these lists could be different, But in the tuple they have the same size
foo ([a],[b],[c],[d]) = concat [[a],[b])
it does not work for the list larger that size one
for example
foo ([1],[2],[3],[4]) // works fine
foo ([1,2] , [2,3] , [3,4] , [5,7]) or any larger size of those list generate error
any hint about to generalize it ?
Much as the source code text [1] means a list with a single element which is the value 1, the source code text [a] means a list with a single element which is the variable a1. It does not mean a list of any size, and a refers to the single element of the list, not the list.
On the left hand side of an equation, [a] would be a pattern that only matches lists containing precisely one element (not zero, and not 2 or 3 or more); the value of that single element can be referred to by a on the right hand side of the equation.
So this code:
foo ([a],[b],[c],[d]) = concat [[a],[b]]
Gives a definition for the result of applying foo to a tuple of 4 singleton lists. It takes the single element in the first two lists (a and b), wraps those up in new singleton lists ([a] and [b]), puts those two lists in another list to make a list of lists ([[a],[b]]), and then passes that list to a function (concat [[a],[b]]).
If any one of the lists has more than one element, or is empty, then this equation doesn't say what the result of foo is. And if there are no other equations helping to define the function foo, then you'll get a pattern match error if you call foo on such non-conforming input.
If (as I suspect) what you wanted was to say that this definition applies to to a tuple of any 4 lists, then you would write it this way:
foo (a,b,c,d) = concat [a,b]
Note the lack of square brackets around a, b, c, and d. This version takes the entirety of the first two lists (a and b), puts those in another list to make a list of lists ([a,b]), and then passes that list to a function (concat [a,b]).
The type of the function (whether inferred from your code or declared by you) says that the things in the tuple that foo receives as argument are lists2; you don't have to put square brackets around every variable that is a list - indeed you can't, because that means something else quite specific! When you want to match against any possible list, you just write a; writing [a] says the list has to be a list of exactly one element, and it's only that element which is freely matched by the variable a, not the list itself.
Any time you use the square bracket syntax you are writing a list with a fixed number of elements,3 and the things in the brackets are individual elements of the list.
1 In a context where [a] is a value expression. If this occurs in a type expression then [a] is the type of lists whose elements are the type a.
2 Technically if you're using inferred types here then there's nothing at all constraining the types of c and d in my suggested version because they are unused, so they don't have to be lists.
3 Unless you're writing a list comprehension (e.g. [x + 1 | x <- [1, 2, 3]]) or a numeric range expression (e.g. [1..n]).
This should work:
foo (a:_,b:_,c:_,d:_)= concat [[a],[b]]
In the above function you just pattern match the first element of the parameters of each list.
A much simpler code:
foo (a:_,b:_,_,_)= [a, b]
In ghci:
ghci> foo ([1],[2],[3],[4])
[1,2]
ghci> foo ([1,2] , [2,3] , [3,4] , [5,7])
[1,2]

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