How to convert from a tuple to a vec or varray in Hacklang? - hacklang

Tuple doesn't seem to implement Traversable. So, how would one convert a Tuple to a vec in Hack?

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.

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.

An array of triplets in repa checked at compile time

First of all, I'm a total newbie in repa and I still consider myself a beginner in Haskell in general.
I need an effective array of triplets of doubles. The naïve approach would be [(Double, Double, Double)] but that's not effective. I thought I could use repa as it is supposed to be very effective. However, I don't know how should I define an array of triplets.
I could do Array U DIM2 Double and store the elements of the triplets in the second dimension (i.e. first index is the index of the triplet and the second index is the element of the triplet). However there is nothing that forces the second dimension to be only of size 3.
I need something like Array U DIM1 Vec3D but that's not possible as Vec3D is not instance of Data.Vector.Unboxed.Base.Unbox.
I may be reading the documentation wrong, but I think Array U DIM1 (Double,Double,Double) is exactly what you want (why don't you try it?). Before you tell me it is inefficient:
As far as I can tell, there is no way of introducing Array U sh u without the constraints Shape sh and Unbox u. Therefore, any Array U sh u will necessarily be efficient and fully unboxed.
In Unbox notice the instance (Unbox a, Unbox b, Unbox c) => Unbox (a, b, c), so Unbox (Double, Double, Double) is derivable.

Haskell - unpacking a list into a custom data type

Is it possible to unpack a list into a data type, without specific pattern matching?
for example
data MyType = MyType Int Int Int deriving Show
let l = [1, 2, 3]
func :: [Int] -> MyType
usage would be
λ: func l
λ: Mytype 1 2 3
What I am trying to achieve.*
I have a list of lists which I pulled in from a CSV file. Each of the lists is a list of type variables. I was hoping there would be a fast way of passing those type variables into the type without having to pattern match ten or more variables.
I personally think you should use the pattern matching....
However, you can use the info in this answer to convert a list to a tuple....
How do I convert a list to a tuple in Haskell?
Then you can use the info in this answer to convert that tuple to params for your constructor
Uncurry for n-ary functions
It works, and is sort of intellectually clean, but it is a lot of work to avoid one line of pattern matching.

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