Convert a list to list with type-constrained fixed length - haskell

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.

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.

Haskell taking in two list with a int and returning a tuple

I am trying to learn haskell and saw a exercise which says
Write two different Haskell functions having the same type:
[a] -> [b] -> Int -> (a,b)
So from my understanding the expressions should take in two lists, an int and return a tuple of the type of the lists.
What i tried so far was
together :: [a] -> [b] -> Int -> (a,b)
together [] [] 0 = (0,0)
together [b] [a] x = if x == a | b then (b,a) else (0,0)
I know I am way off but any help is appreciated!
First you need to make your mind up what the function should return. That is partly determined by the signature. But still you can come up with a lot of functions that return different things, but have the same signature.
Here one of the most straightforward functions is probably to return the elements that are placed on the index determined by the third parameter.
It makes no sense to return (0,0), since a and b are not per se numerical types. Furthermore if x == a | b is not semantically valid. You can write this as x == a || x == b, but this will not work, since a and b are not per se Ints.
We can implement a function that returns the heads of the two lists in case the index is 0. In case the index is negative, or at least one of the two lists is exhausted, then we can raise an error. I leave it as an exercise what to do in case the index is greater than 0:
together :: [a] -> [b] -> Int -> (a,b)
together [] _ = error "List exhausted"
together _ [] = error "List exhausted"
together (a:_) (b:_) 0 = (a, b)
together (a:_) (b:_) n | n < 0 = error "Negative index!"
| …
you thus still need to fill in the ….
I generally dislike those "write any function with this signature"-type excercises precisely because of how arbitrary they are. You're supposed to figure out a definition that would make sense for that particular signature and implement it. In a lot of cases, you can wing it by ignoring as many arguments as possible:
fa :: [a] -> [b] -> Int -> (a,b)
fa (a:_) (b:_) _ = (a,b)
fa _ _ _ = error "Unfortunately, this function can't be made total because lists can be empty"
The error here is the important bit to note. You attempted to go around that problem by returning 0s, but this will only work when 0 is a valid value for types of a and b. Your next idea could be some sort of a "Default" value, but not every type has such a concept. The key observation is that without any knowledge about a type, in order to produce a value from a function, you need to get this value from somewhere else first*.
If you actually wanted a more sensible definition, you'd need to think up a use for that Int parameter; maybe it's the nth element from each
list? With the help of take :: Int -> [a] -> [a] and head :: [a] -> a this should be doable as an excercise.
Again, your idea of comparing x with a won't work for all types; not every type is comparable with an Int. You might think that this would make generic functions awfully limited; that's the point where you typically learn about how to express certain expectations about the types you get, which will allow you to operate only on certain subsets of all possible types.
* That's also the reason why id :: a -> a has only one possible implementation.
Write two different Haskell functions having the same type:
[a] -> [b] -> Int -> (a,b)
As Willem and Bartek have pointed out, there's a lot of gibberish functions that have this type.
Bartek took the approach of picking two based on what the simplest functions with that type could look like. One was a function that did nothing but throw an error. And one was picking the first element of each list, hoping they were not empty and failing otherwise. This is a somewhat theoretical approach, since you probably don't ever want to use those functions in practice.
Willem took the approach of suggesting an actually useful function with that type and proceeded to explore how to exhaust the possible patterns of such a function: For lists, match the empty list [] and the non-empty list a:_, and for integers, match some stopping point, 0 and some categories n < 0 and ….
A question that arises to me is if there is any other equally useful function with this type signature, or if a second function would necessarily have to be hypothetically constructed. It would seem natural that the Int argument has some relation to the positions of elements in [a] and [b], since they are also integers, especially because a pair of single (a,b) is returned.
But the only remotely useful functions (in the sense of not being completely silly) that I can think of are small variations of this: For example, the Int could be the position from the end rather than from the beginning, or if there's not enough elements in one of the lists, it could default to the last element of a list rather than an error. Neither of these are very pleasing to make ("from the end" conflicts with the list being potentially infinite, and having a fall-back to the last element of a list conflicts with the fact that lists don't necessarily have a last element), so it is tempting to go with Bartek's approach of writing the simplest useless function as the second one.

The meaning of the universal quantification

I am trying to understand the meaning of the universal quantification from the following page http://dev.stephendiehl.com/hask/#universal-quantification.
I am not sure, if I understand this sentence correctly
The essence of universal quantification is that we can express
functions which operate the same way for a set of types and whose
function behavior is entirely determined only by the behavior of all
types in this span.
Let`s take the function from the example:
-- ∀a. [a]
example1 :: forall a. [a]
example1 = []
What I can do with the function example1 is, to use every functions, that is defined for List type.
But I did not get the exactly purpose of the universal quantification in Haskell.
I need a collection of numbers, and I need to be able to easily insert into the middle of the list, so I decide on making a linked list. Being a savvy Hask-- programmer (Hask-- being the variant of Haskell that does not have universal quantification!), I quickly whip up a type and a length function without trouble:
data IntLinkedList = IntNil | IntCons Int IntLinkedList
length_IntLinkedList :: IntLinkedList -> Int
length_IntLinkedList IntNil = 0
length_IntLinkedList (IntCons _ tail) = 1 + length_IntLinkedList tail
Later I realize it would be handy to have a variant type that can store numbers not quite as big as 1 and not quite as small as 0. No problem...
data FloatLinkedList = FloatNil | FloatCons Float FloatLinkedList
length_FloatLinkedList :: FloatLinkedList -> Int
length_FloatLinkedList FloatNil = 0
length_FloatLinkedList (FloatCons _ tail) = 1 + length_FloatLinkedList tail
Boy that code looks awfully familiar! And if, later, I discover it would be nice to have a variant that can store Strings I am once again left copying and pasting the exact same code, and tweaking the exact same places that are specific to the contained type. Wouldn't it be nice if there were a way to just cook up a linked list once and for all that could contain elements of any single type, and a length function that worked uniformly no matter what elements it had? After all, our length functions above didn't even care what values the elements had. In Haskell, this is exactly what universal quantification gives you: a way to write a single function which works with an entire collection of types.
Here's how it looks:
data LinkedList a = Nil | Cons a (LinkedList a)
length_LinkedList :: forall a. LinkedList a -> Int
length_LinkedList Nil = 0
length_LinkedList (Cons _ tail) = 1 + length_LinkedList tail
The forall says that this function for all variants of linked lists -- linked lists of Ints, linked lists of Floats, linked lists of Strings, linked lists of functions that take FibbledyGibbets and return linked lists of tuples of Grazbars and WonkyNobbers, ...
How nice! Now instead of separate IntLinkedList and FloatLinkedList types, we can just use LinkedList Int and LinkedList Float for that, and length_LinkedList, implemented once, works for both.

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.

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]

Resources