How do I convert a list to a tuple in Haskell? - haskell

How can I best convert a list to a tuple in Haskell:
[1,2,3,4,5,6] -> (1,2,3,4,5,6)

In a general way, you can't. Each size of tuple is a distinct type, whereas lists of any length are a single type. Thus, there's no good way to write a function that takes a list and returns a tuple of the same length--it wouldn't have a well-defined return type.
For instance, you could have functions like:
tuplify2 :: [a] -> (a,a)
tuplify2 [x,y] = (x,y)
tuplify3 :: [a] -> (a,a,a)
tuplify3 [x,y,z] = (x,y,z)
...but not one that does the job of both.
You can write a generic version using various kinds of meta-programming, but you'd rarely want to.
Note that the same problem applies to other things, such as writing class instances for various tuples--take a look at the source code for Data.Tuple from the standard libraries!

Template Haskell is as close as you can get due to type checking if you want to extract a variable number of elements, since (a,b) and (a,b,c) have different types.
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
tuple :: Int -> ExpQ
tuple n = do
ns <- replicateM n (newName "x")
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)
Then:
$(tuple 6) [1,2,3,4,5,6] == (1,2,3,4,5,6)
$(tuple 3) "abc" == ('a','b','c')
But in general, if you need this answer, then you're asking the wrong question somewhere.
If you just want flat random access, perhaps the better option would be to use an Array.

If feel like I am about to advise you to point a gun at your foot and trust you not to shoot.
> list2Tuple lst = read $ "(" ++ (init.tail.show) lst ++ ")"
> list2Tuple [1,2,3] :: (Int, Int, Int)
(1,2,3)
> list2Tuple [1,2,3,4] :: (Int, Int, Int, Int)
(1,2,3,4)
This will work up to the what ever length of tuple Show and Read are defined for.

Tuples and lists are very different things. About the best you can do is to manually write a conversion function:
toTuple :: [a] -> (a,a,a,a,a,a)
toTuple [a,b,c,d,e,f] = (a,b,c,d,e,f)
Notice how different the types are: the single variable of the list expands to six variables for the tuple. So you'll need one function for each size of tuple.

I find it difficult to make cogent explanations of Template Haskell manipulations, but here is a demonstration:
> :m +Language.Haskell.TH
> :set -XTemplateHaskell
> runQ [| [1,2,3,4,5,6] |] >>= putStrLn . pprint
[1, 2, 3, 4, 5, 6]
> runQ [| [1,2,3,4,5,6] |] >>= \ (ListE exps) -> putStrLn (pprint (TupE exps))
(1, 2, 3, 4, 5, 6)

I don't think it's possible to do this in Haskell, for a list of arbitrary length not known at compile time. Template Haskell can't do it because it operates only at compile time. I ran into a case where I needed to do precisely this, and I had to work around it. A database library expects different-length tuples for query arguments, but I have an arbitrary-length list. So I have to skirt around the library interface. It would be nice if it could take a list.
Basically the issue is that different-length tuples are different types. But the Haskell compiler has to know at compile type what types might exist at runtime. Converting an arbitrary-length list into a tuple at run time could create some type it didn't know about at compile time.

You can in fact do better than manually writing one function per tuple-size if you use quasi-quotation as explained here. However, I would wonder about code where you expect to use this generically.

When dealing with command line arguments you can use getArgs, that function will give you a list with strings:
getArgs :: IO [String]
Link: https://hackage.haskell.org/package/base-4.16.0.0/docs/System-Environment.html#v:getArgs
When I work with command line arguments I prefer to work with tuples instead of a list, so I convert the list to a tuple. See below:
import System.Environment
main = do
args <- getArgs
let (a:b:c) = args
print a
Calling the program (in PowerShell):
PS C:\Haskell> runghc convertListToTuple goodday to you
"goodday"

Related

Haskell Pattern Matching (beginner)

I have to implement a small programm in Haskell that increments/decrements a result by what in the console line is. For example if we have -a in the console the results must be 0, if -b the result must be incremented with 6 and so on. I have to do this with pattern matching.
I haven't used Haskell until now and I find it pretty hard to understand. I have this to start with:
import System.Environment
main = getArgs >>= print . (foldr apply 0) . reverse
apply :: String -> Integer -> Integer
I don't understand what in the main is. What does it make and the reverse from end, what does it do? As I've read on the internet the getArgs function gives me the values from the console line. But how can I use them? Are there are equivalent functions like for/while in Haskell?
Also, if you have some examples or maybe could help me, I will be very thankful.
Thanks!
This is not beginner-friendly code. Several shortcuts are taken there to keep the code very compact (and in pointfree form). The code
main = getArgs >>= print . (foldr apply 0) . reverse
can be expanded as follows
main = do
args <- getArgs
let reversedArgs = reverse args
result = foldr apply 0 reversedArgs
print result
The result of this can be seen as follows. If the command line arguments are, say, args = ["A","B","C"], then we get reversedArgs = ["C","B","A"] and finally
result = apply "C" (apply "B" (apply "A" 0))
since foldr applies the function apply in such way.
Honestly, I'm unsure about why the code uses reverse and foldr for your task. I would have considered foldl (or, to improve performance, foldl') instead.
I expect the exercise is not to touch the given code, but to expand on it to perform your function. It defines a complicated-looking main function and declares the type of a more straight forward apply, which is called but not defined.
import System.Environment -- contains the function getArgs
-- main gets arguments, does something to them using apply, and prints
main = getArgs >>= print . (foldr apply 0) . reverse
-- apply must have this type, but what it does must be elsewhere
apply :: String -> Integer -> Integer
If we concentrate on apply, we see that it receives a string and an integer, and returns an integer. This is the function we have to write, and it can't decide control flow, so we can just get to it while hoping the argument handling works out.
If we do want to figure out what main is up to, we can make a few observations. The only integer in main is 0, so the first call must get that as its second argument; later ones will be chained with whatever is returned, as that's how foldr operates. r stands for from the right, but the arguments are reversed, so this still processes arguments from the left.
So I could go ahead and just write a few apply bindings to make the program compile:
apply "succ" n = succ n
apply "double" n = n + n
apply "div3" n = n `div` 3
This added a few usable operations. It doesn't handle all possible strings.
$ runhaskell pmb.hs succ succ double double succ div3
3
$ runhaskell pmb.hs hello?
pmb.hs: pmb.hs:(5,1)-(7,26): Non-exhaustive patterns in function apply
The exercise should be about how you handle the choice of operation based on the string argument. There are several options, including distinct patterns as above, pattern guards, case and if expressions.
It can be useful to examine the used functions to see how they might fit together. Here's a look at a few of the used functions in ghci:
Prelude> import System.Environment
Prelude System.Environment> :t getArgs
getArgs :: IO [String]
Prelude System.Environment> :t (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Prelude System.Environment> :t print
print :: Show a => a -> IO ()
Prelude System.Environment> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
Prelude System.Environment> :t foldr
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
Prelude System.Environment> :t reverse
reverse :: [a] -> [a]
This shows that all the strings come out of getArgs, it and print operate in the IO monad, which must be the m in >>=, and . transfers results from the right function into arguments for the left function. The type signature alone doesn't tell us what order foldr handles things, though, or what reverse does (though it can't create new values, only reorder including repetition).
As a last exercise, I'll rewrite the main function in a form that doesn't switch directions as many times:
main = print . foldl (flip apply) 0 =<< getArgs
This reads from right to left in a data flow sense and handles arguments from left to right because foldl performs left-associative folding. flip is just there to match the argument order for apply.
As suggested in the comment, hoogle is a great tool.
To find out what exactly you get from getArgs you can search for it on hoogle:
https://hackage.haskell.org/package/base-4.11.1.0/docs/System-Environment.html#v:getArgs
As you can see, it's of type IO [String].
Since I don't know how familiar you are with the IO abstractions yet, we'll just say that the right part of >>= gets those as argument.
The arguments for a call like ./a.out -a -b --asdf Hi will then be a list of strings:
["-a", "-b", "--asdf", "Hi"].
The fold + reverse in the main will then do some magic, and your apply function will be called with each string in the list and the previous return value (0 for the first invocation).
In Haskell, String is the same as [Char] with a bit of compiler sugar, so you can match on strings like you would on regular lists in your definition of apply.

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)

Is it possible to define a list recursively in Haskell?

In several programming languages (including JavaScript, Python, and Ruby), it's possible to place a list inside itself, which can be useful when using lists to represent infinitely-detailed fractals. However, I tried doing this in Haskell, and it did not work as I expected:
--aList!!0!!0!!1 should be 1, since aList is recursively defined: the first element of aList is aList.
main = putStrLn $ show $ aList!!0!!0!!1
aList = [aList, 1]
Instead of printing 1, the program produced this compiler error:
[1 of 1] Compiling Main ( prog.hs, prog.o )
prog.hs:3:12:
Occurs check: cannot construct the infinite type: t0 = [t0]
In the expression: aList
In the expression: [aList, 1]
In an equation for `aList': aList = [aList, 1]
Is it possible to put an list inside itself in Haskell, as I'm attempting to do here?
No, you can't. First off, there's a slight terminological confusion: what you have there are lists, not arrays (which Haskell also has) , although the point stands either way. So then, as with all things Haskell, you must ask yourself: what would the type of aList = [aList, 1] be?
Let's consider the simpler case of aList = [aList]. We know that aList must be a list of something, so aList :: [α] for some type α. What's α? As the type of the list elements, we know that α must be the type of aList; that is, α ~ [α], where ~ represents type equality. So α ~ [α] ~ [[α]] ~ [[[α]]] ~ ⋯ ~ [⋯[α]⋯] ~ ⋯. This is, indeed, an infinite type, and Haskell forbids such things.
In the case of the value aList = [aList, 1], you also have the restriction that 1 :: α, but all that that lets us conclude is that there must be a Num α constraint (Num α => [⋯[α]⋯]), which doesn't change anything.
The obvious next three questions are:
Why do Haskell lists only contain one type of element?
Why does Haskell forbid infinite types?
What can I do about this?
Let's tackle those in order.
Number one: Why do Haskell lists only contain one type of element? This is because of Haskell's type system. Suppose you have a list of values of different types: [False,1,2.0,'c']. What's the type of the function someElement n = [False,1,2.0,'c'] !! n? There isn't one, because you couldn't know what type you'd get back. So what could you do with that value, anyway? You don't know anything about it, after all!
Number two: Why does Haskell forbid infinite types? The problem with infinite types is that they don't add many capabilities (you can always wrap them in a new type; see below), and they make some genuine bugs type-check. For example, in the question "Why does this Haskell code produce the ‘infinite type’ error?", the non-existence of infinite types precluded a buggy implementation of intersperse (and would have even without the explicit type signature).
Number three: What can I do about this? If you want to fake an infinite type in Haskell, you must use a recursive data type. The data type prevents the type from having a truly infinite expansion, and the explicitness avoids the accidental bugs mentioned above. So we can define a newtype for an infinitely nested list as follows:
Prelude> newtype INL a = MkINL [INL a] deriving Show
Prelude> let aList = MkINL [aList]
Prelude> :t aList
aList :: INL a
Prelude> aList
MkINL [MkINL [MkINL [MkINL ^CInterrupted.
This got us our infinitely-nested list that we wanted—printing it out is never going to terminate—but none of the types were infinite. (INL a is isomorphic to [INL a], but it's not equal to it. If you're curious about this, the difference is between isorecursive types (what Haskell has) and equirecursive types (which allow infinite types).)
But note that this type isn't very useful; the only lists it contains are either infinitely nested things like aList, or variously nested collections of the empty list. There's no way to get a base case of a value of type a into one of the lists:
Prelude> MkINL [()]
<interactive>:15:8:
Couldn't match expected type `INL a0' with actual type `()'
In the expression: ()
In the first argument of `MkINL', namely `[()]'
In the expression: MkINL [()]
So the list you want is an arbitrarily nested list. The 99 Haskell Problems has a question about these, which requires defining a new data type:
data NestedList a = Elem a | List [NestedList a]
Every element of NestedList a is either a plain value of type a, or a list of more NestedList as. (This is the same thing as an arbitrarily-branching tree which only stores data in its leaves.) Then you have
Prelude> data NestedList a = Elem a | List [NestedList a] deriving Show
Prelude> let aList = List [aList, Elem 1]
Prelude> :t aList
aList :: NestedList Integer
Prelude> aList
List [List [List [List ^CInterrupted.
You'll have to define your own lookup function now, and note that it will probably have type NestedList a -> Int -> Maybe (NestedList a)—the Maybe is for dealing with out-of-range integers, but the important part is that it can't just return an a. After all, aList ! 0 is not an integer!
Yes. If you want a value that contains itself, you'll need a type that contains itself. This is no problem; for example, you might like rose trees, defined roughly like this in Data.Tree:
data Tree a = Node a [Tree a]
Now we can write:
recursiveTree = Node 1 [recursiveTree]
This isn't possible with the list type in Haskell, since each element has to be of the same type, but you could create a data type to do it. I'm not exactly sure why you'd want to, though.
data Nested a
= Value a
| List [Nested a]
deriving (Eq, Show)
nested :: Nested Int
nested = List [nested, Value 1]
(!) :: Nested a -> Int -> Nested a
(!) (Value _) _ = undefined
(!) (List xs) n = xs !! n
main = print $ nested ! 0 ! 0 ! 1
This will print out Value 1, and this structure could be of some use, but I'd imagine it's pretty limited.
There were several answers from "yes you can" to "no you absolutely cannot". Well, both are right, because all of them address different aspects of your question.
One other way to add "array" to itself, is permit a list of anything.
{-# LANGUAGE ExistentialQuantification #-}
data T = forall a. T a
arr :: [T]
arr = [T arr, T 1]
So, this adds arr to itself, but you cannot do anything else with it, except prove it is a valid construct and compile it.
Since Haskell is strongly typed, accessing list elements gives you T, and you could extract the contained value. But what is the type of that value? It is "forall a. a" - can be any type, which in essence means there are no functions at all that can do anything with it, not even print, because that would require a function that can convert any type a to String. Note that this is not specific to Haskell - even in dynamic languages the problem exists; there is no way to figure out the type of arr !! 1, you only assume it is a Int. What makes Haskell different to that other language, is that it does not let you use the function unless you can explain the type of the expression.
Other examples here define inductive types, which is not exactly what you are asking about, but they show the tractable treatment of self-referencing.
And here is how you could actually make a sensible construct:
{-# LANGUAGE ExistentialQuantification #-}
data T = forall a. Show a => T a
instance Show T where -- this also makes Show [T],
-- because Show a => Show [a] is defined in standard library
show (T x) = show x
arr :: [T]
arr = [T arr, T 1]
main = print $ arr !! 1
Now the inner value wrapped by T is restricted to be any instance of Show ("implementation of Show interface" in OOP parlance), so you can at least print the contents of the list.
Note that earlier we could not include arr in itself only because there was nothing common between a and [a]. But the latter example is a valid construct once you can determine what's the common operation that all the elements in the list support. If you can define such a function for [T], then you can include arr in the list of itself - this function determines what's common between certain kinds of a and [a].
No. We could emulate:
data ValueRef a = Ref | Value a deriving Show
lref :: [ValueRef Int]
lref = [Value 2, Ref, Value 1]
getValue :: [ValueRef a] -> Int -> [ValueRef a]
getValue lref index = case lref !! index of
Ref -> lref
a -> [a]
and have results:
>getValue lref 0
[Value 2]
>getValue lref 1
[Value 2,Ref,Value 1]
Sure, we could reuse Maybe a instead of ValueRef a

Haskell - defining functions

I am new to programming and to Haskell. I'm having trouble understanding how to define a function. Let's say I want a function that will return element in position a of a list [b]. For a specific a and [b] I can do this in the interpreter:
Prelude> [2, 3, 5, 6] !! 1
Prelude> 3
But I run into trouble if I try to make a function, either in the interpreter or in a text editor that is then loaded:
Prelude> let getElement a [b] = [b] !! a
Prelude> getElement 1 [2, 3, 5, 6]
***Exception: <interactive>:17:5-27: Non-exhaustive pattern in function getElement
let getElement a [b] = [b] !! a
Your function takes one argument a of type Int, since (!!) second parameter is an Int, and [b] pattern matches on a list with one element.
It looks like you were trying to tell the complier that the second parameter should be a list. To do this you normally use the type signature.
In a file:
getElement :: Int -> [b] -> b
getElement a bs = bs !! a
This type of function is considered partial since you can give it an integer that causes the function to fail and throw an exception, such as a negative number or trying to access an index larger then the list. This chapter in real world Haskell has some information on partial function. The Haskell wiki in on the programming guidelines page has some advise too.
You may want to look at the
safe package and how they define headMay for a total, rather then partial, implementation.
Edit: b changed to bs as recommend by Rein Henrichs below, as he points out it does make it easier to read and is a rather common idiom.

Type-conditional controls in Haskell

I'm going through the 99 Haskell problems to build my proficiency with the language. On problem 7 ("Flatten a nested list structure"), I found myself wanting to define a conditional behavior based on the type of argument passed to a function. That is, since
*Main> :t 1
1 :: (Num t) => t
*Main> :t [1,2]
[1,2] :: (Num t) => [t]
*Main> :t [[1],[2]]
[[1],[2]] :: (Num t) => [[t]]
(i.e. lists nested at different levels have different data types) it seems like I should be able to write a function that can read the type of the argument, and then behave accordingly. My first attempt was along these lines:
listflatten l = do
if (:t l) /= ((Num t) => [t]) then
listflatten (foldl (++) [] l)
else id l
But when I try to do that, Haskell returns a parse error. Is Haskell flexible enough to allow this sort of type manipulation, do I need to find another way?
1. Use pattern matching instead
You can solve that problem without checking for data types dynamically. In fact, it is very rarely needed in Haskell. Usually you can use pattern matching instead.
For example, if you have a type
data List a = Elem a | Nested [List a]
you can pattern match like
flatten (Elem x) = ...
flatten (Nested xs) = ...
Example:
data List a = Elem a | Nested [List a]
deriving (Show)
nested = Nested [Elem 1, Nested [Elem 2, Elem 3, Nested [Elem 4]], Elem 5]
main = print $ flatten nested
flatten :: List a -> [a]
flatten (Elem x) = [x]
flatten (Nested lists) = concat . map flatten $ lists
map flatten flattens every inner list, thus it behaves like [List a] -> [[a]], and we produce a list of lists here. concat merges all lists together (concat [[1],[2,3],[4]] gives [1,2,3,4]). concat . map flatten is the same as concatMap flatten.
2. To check types dynamically, use Data.Typeable
And if on some rare occasion (not in this problem) you really need to check types dynamically, you can use Data.Typeable type class and its typeOf function. :t works only in GHCI, it is not part of the language.
ghci> :m + Data.Typeable
ghci> typeOf 3 == typeOf "3"
False
ghci> typeOf "a" == typeOf "b"
True
Likely, you will need to use DeriveDataTypeable extension too.
(Sorry about the length—I go a little bit far afield/in excessive depth. The CliffsNotes version is "No, you can't really do what you want because types aren't values and we can't give your function a sensible type; use your own data type.". The first and the fifth paragraph, not counting this one or the code block, explain the core of what I mean by that first part, and the rest of the answer should provide some clarification/detail.)
Roughly speaking, no, this is not possible, for two reasons. The first is the type-dispatch issue. The :t command is a feature (an enormously useful one) of GHCi, and isn't a Haskell function. Think about why: what type would it have? :t :: a -> ?? Types themselves aren't values, and thus don't have a type. It's two different worlds. So the way you're trying to do this isn't possible. Also note that you have a random do. This is bad—do notation is a syntactic sugar for monadic computation, and you aren't doing any of that. Get rid of it!
Why is this? Haskell has two kinds polymorphism, and the one we're concerned with at the moment is parametric polymorphism. This is what you see when you have a type like concat :: [[a]] -> a. That a says that one single definition of concat must be usable for every possible a from now until the end of time. How on earth would you type flatten using this scheme? It's just not possible.
You're trying to call a different function, defined ad-hoc, for different kinds of data. This is called, shockingly, ad-hoc polymorphism. For instance, in C++, you could define the following function:
template <typename T>
void flatten(vector<T>& v) { ... }
template <typename T>
void flatten(vector< vector<T> >& v) { ... }
This would allow you do different things for different types. You could even have template <> void flatten(int) { ... }! You can accomplish this in Haskell by using type classes such as Num or Show; the whole point of a type signature like Show a => a -> String is that a different function can be called for different as. And in fact, you can take advantage of this to get a partial solution to your problem…but before we do, let's look at the second problem.
This issue is with the list you are trying to feed in. Haskell's list type is defined as (roughly) data [a] = [] | a : [a]. In other words, every element of a list must have the same type; a list of ints, [Int], contains only ints, Int; and a list of lists of ints, [[Int]], contains only lists of ints, [Int]. The structure [1,2,[3,4],5] is illegal! Reading your code, I think you understand this; however, there's another ramification. For similar reasons, you can't write a fully-generic flatten function of type flatten :: [...[a]...] -> [a]. Your function also has to be able to deal with arbitrary nesting depth, which still isn't possible with a list. You need [a], [[a]], and so on to all be the same type!
Thus, to get all of the necessary properties, you want a different type. The type you want has a different property: it contains either nothing, a single element followed by the rest of the value, or a nested list of elements followed by the rest of the value. In other words, something like
data NList a = Nil
| a :> NList a
| (NList a) :>> NList a
deriving (Eq, Show)
infixr 5 :>, :>>
Then, instead of the list [1,2,3] == 1 : 2 : 3 : [], you would write 1 :> 2 :> 3 :> Nil; instead of Lisp's (1 (2 3) 4 ()), you would write
1 :> (2 :> 3 :> Nil) :>> 4 :> Nil :>> Nil. You can even begin to define functions to manipulate it:
nhead :: NList a -> Either a [a]
nhead Nil = error "nhead: Empty NList."
nhead (h :> _) = Left a
nhead (h :>> _) = Right a
ntail :: NList a -> NList a
ntail Nil = error "nhead: Empty NList."
ntail (_ :> t) = t
ntail (_ :>> t) = t
Admittedly, you might find this a bit clunky (or perhaps not), so you might try to think about your type differently. Another option, which the Haskell translation of the 99 problems uses, is to realize that everything in a nested list is either a single item or a list of nested lists. This translation gives you
data NestedList a = Elem a
| List [NestedList a]
deriving (Eq, Show)
The two above lists then become List [Elem 1, Elem 2, Elem 3] and List [Elem 1, List [Elem 2, Elem 3], Elem 4, List []]. As for how to flatten them—since you're trying to learn from the 99 problems, that I won't say :) And after all, you seem to have a handle on that part of the problem.
Now, let's return to type classes. I lied a bit when I said that you couldn't write something which took an arbitrarily-nested list—you can, in fact, using type classes and some GHC extensions. Now, before I continue, I should say: don't use this! Seriously. The other technique is almost definitely a better choice. However, this technique is cool, and so I will present it here. Consider the following code:
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, UndecidableInstances #-}
class Flattenable f e where
flatten :: f -> [e]
instance Flattenable a a where
flatten = return
instance Flattenable f e => Flattenable [f] e where
flatten = concatMap flatten
We are creating a type class whose instances are the things we can flatten. If we have Flattenable f e, then f should be a collection, in this case a list, whose elements are ultimately of type e. Any single object is such a collection, and its element type is itself; thus, the first instance declaration allows us to flatten anything into a singleton list. The second instance declaration says that if we can flatten an f into a list of es, then we can also flatten a list of fs into a list of es by flattening each f and sticking the resulting lists together. This recursive class definition defines the function recursively for the nested list types, giving you the ability to flatten a list of any nesting with the single function flatten: [1,2,3], [[4,5],[6]], [[[7,8],[9]],[[10]],[[11],[12]]], and so on.
However, because of the multiple instances and such, it does require a single type annotation: you will need to write, for instance, flatten [[True,False],[True]] :: [Bool]. If you have something that's type class-polymorphic within your lists, then things are a little stricter; you need to write flatten [[1],[2,3 :: Int]] :: [Int], and as far as I can tell, the resulting list cannot be polymorphic itself. (However, I could well be wrong about this last part, as I haven't tried everything by any means.) For a similar reason, this is too open—you could declare instance Flattenable [f] () where flatten = [()] if you wanted too. I tried to get things to work with type families/functional dependencies in order to remove some of these problems, but thanks to the recursive structure, couldn't get it to work (I had no e and a declaration along the lines of type Elem a = a and type Elem [f] = Elem f, but these conflicted since [f] matches a). If anyone knows how, I'd very much like to see it!
Again, sorry about the length—I tend to start blathering when I get tired. Still, I hope this is helpful!
You are confusing the interactive command :t in the interpreter with a built-in function. You cannot query the type at runtime.
Look at the example for that problem:
flatten (List [Elem 1, List [Elem 2, List [Elem 3, Elem 4], Elem 5]])
As you see, the problem wants you to create your own data structure for arbitrarily nested lists.
Normal haskell lists can not be arbitrarily nested. Every element of the list has to have the same type, statically known, which is why it makes no sense to check the type of the elements dynamically.
In general haskell does not allow you to create a list of different types and then check the type at runtime. You could use typeclasses to define different behaviors for flatten with different types of arguments, but that still wouldn't give you arbitrarily nested lists.

Resources