How can I declare an empty tuple? - haskell

I can declare empty list as [], but, how can I declare empty tuple?
I have tried:
for ( , )
ghci>(1,0 ) : [(,)]
but it gives me an error!

A tuple is a type that is always the same length and always has the same types. So (Int, Int) is a different type from (Int, Int, Int) and a different type from (Int, String).
With this in mind, you could have an empty tuple. However, this would just be a type with a single value. This type is written as () and pronounced unit. The only value of this type is also ().

Note that (,) and friends act as functions.
ghci> (,) 2 3
(2,3)
Lists have two constructors: [] and :, which gives them the possibility of emptiness ([] representing "empty"). Tuples, however, only have one constructor each. (,) is the only constructor for the two-tuple type, meaning that tuples do not provide the possibility of emptiness. Whenever you have a two-tuple, you are guaranteed that it actually has two elements in it.

Related

Product type convert to tuple

I've got this
data Pair = P Int Double deriving Show
myP1 = P 1 2.0
getPairVal (P i d) = (i,d)
getPairVal' (P i d) = (,) i d
which work, both producing (1,2.0). Is there any way to make a straight (,) myP1 work? But then this would require some sort of "cast" I'm guessing.
data Pair2 = P2 (Int, Double) deriving Show
is a tuple version that is "handier" sort of
myP21 = (5,5.0)
So what would be the advantage of a product type like Pair with or without a tuple type definition? I seem to remember SML having a closer relationship, i.e., every product type was a tuple type. In math, anything that's a "product" produces a tuple. Haskell apparently not.
why shouldn't a straight (,) myP1 work?
Well, (,) is a function that takes two values and makes a tuple out of them. P 1 2.0 is not two values: it is a single value of type Pair, which contains two fields. But (,) (P 1 2.0) is a well-typed expression: it has built the left half of a tuple, and needs one more argument for the right half. So:
let mkTuple = (,) (P 1 2.0)
in mkTuple "hello"
evaluates to
(P 1 2.0, "hello")
Why should we define types like Pair instead of using tuples? user202729 linked to Haskell: Algebraic data vs Tuple in a comment, which is a good answer to that question.
But one other approach you could use would be to define a newtype wrapping a tuple, so that you have a distinct named type, but the same runtime representation as a tuple:
newtype Pair2 = P2 (Int, Double) deriving Show
If you use newtype instead of data, you do get a simple conversion function, which you might choose to think of as a cast: Data.Coerce.coerce. With that, you could write
myP21 = coerce (5, 5.0)
and vice versa. This approach is primarily used when you want new typeclass instances for existing types. If you need a new domain type composed of two values, I'd still encourage you to default to using a data type with two fields unless there is a compelling reason not to.

Check if tuple or triple in 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.

How can I get an Int from the tuple in Haskell

I am new to Haskell, and currently looking for a way to extract or delete the first Int in a tuple. Is there a built-in Haskell function to do that?
For instance:
tuple :: (Int)
tuple = (1,2,3,4,5)
tuple !! 0 =
As defined in the OP, the type of tuple is this:
Prelude> tuple = (1,2,3,4,5)
Prelude> :t tuple
tuple
:: (Num t4, Num t3, Num t2, Num t1, Num t) => (t4, t3, t2, t1, t)
There's no type (Int). Instead, the type is (t4, t3, t2, t1, t), where each of those five types has to be a Num instance. There's more than a single type to chose from, and since all five types can vary independently of each other, the type could be (Int, Word, Float, Integer, Int).
The reason for this is that each literal in the definition (1, 2, etc.) could be interpreted as any of those types, and when you write an expression like that, the compiler keeps your options open.
If you want it to be a tuple exclusively made up of Int values, you can declare that:
tuple :: (Int, Int, Int, Int, Int)
tuple = (1,2,3,4,5)
If you want the first element of the tuple, you can use pattern matching to extract that information:
Prelude> (x, _, _, _, _) = tuple
Prelude> x
1
The above expression uses wildcards to ignore the other four elements of the tuple, but if you need one or more of those, you can bind to named values as well:
Prelude> (x, _, z, _, _) = tuple
Prelude> z
3
As Thomas M. DuBuisson points out in a comment to the OP, however, you'd probably be better off with other language constructs than large tuples.
If I may venture a guess, I suppose the OP is actually about lists, not tuples. Certain languages (particularly dynamic languages) don't make much of a distinction between lists and tuples. This makes some sense in a dynamic language where types are unknown at compile-time.
Haskell, however, is a statically typed language, and lists and tuples are different.
A tuple is a data structure with a fixed length, but where you can flexibly choose the type of each individual element.
A list is a data structure with a fixed element type, but where you can vary the length.
Perhaps you're looking for a list of integers:
list :: [Int]
list = [1,2,3,4,5]
Given such a list, you can, for instance, use the !! operator to extract the first element:
Prelude> list !! 0
1
Do note, however, that !! is unsafe, because if you give it an out-of-range index, it's going to throw an exception.
You can use the lens library:
tuple :: (Int, Int, Int, Int, Int)
tuple = (1,2,3,4,5)
secondElement = tuple ^. _2 -- One indexed
For tuples with exactly 2 elements you can use fst and snd from Prelude to get the first and second element respectively

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)

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)

Resources