Need help in representing the List-like type in gleam!

Hello, I was learning gleam and I was in the process of creating an exercise in it.

The exercise is known as Flatten Array. Basically in this question, I will have to take something like this

x = [1, 2, [3, 4, 5, 6], 7]

and the result should be:

x = [1, 2, 3, 4, 5, 6, 7]

Now, in order to solve this, I looked up the (gleam docs)[gleam/list - gleam_stdlib] for flatten method, and it takes an object of type List(List(a)).

So it assumes that the list will be of the format

x = [[1], [2], [3, 4, 5, 6], [7]]

As you can see that subsequent type is a List(List(int)).

But if you look into x, the type is different.
How, can I represent this type in gleam?

Any help will be greatly appreciated!

I do not know Gleam at all. Still, the following might prove useful.

In Haskell, x = [1, 2, [3, 4, 5, 6], 7] would be ill-typed. Simple as that.

So lists are out. You need another data type. Perhaps the following.

data ArbitrarilyNested a = One a | Several [ArbitrarilyNested a]

Then you can define

x = Several [One 1, One 2, Several [One 3, One 4, One 5, One 6], One 7]

flatten would be like this:

flatten :: ArbitrarilyNested a -> [a]
flatten = \case
  One x -> pure x
  Several xs -> xs >>= flatten


This definitely is a somewhat weird scenario though. I cannot think of real-world applications of such a type right now.

@MatthijsBloms analogy to Haskell checks out.
x = [1, 2, [3, 4, 5, 6], 7] doesn’t compile in Gleam, all members of the list have to have the same type.

Not all exercises make sense to implement in all languages, this might be an exercise that’s not fitting for Gleam. If you look around I’m pretty sure that you will find that other statically typed functional language tracks don’t implement this exercise. (just checked Haskell and F#) In statically typed OO languages like Java you can implement it with the built in List class. You let the type of the list elements be Object, the parent class of all classes: java/ at main · exercism/java · GitHub. But even then this is very dubious style and should be avoided whenever possible.
On the other hand, the way I understand the purpose of the problem specifications, it’s fine to let the students implement solutions that are awkward to realize in a language, to let them experience that the pros and cons of languages (comparing how difficult it is to solve exercise X in different languages). So I’m interested what people with more experience in statically typed functional languages / Gleam think about this. :)

Actually I was implementing the exercise for flattening the list and stumbled upon this… so kinda got confused. I think this exercise is not possible to implement in gleam.

But, doesn’t this behave as a restriction. I mean JS, python can work on these types of lists but gleam cannot?

Yes, type systems are generally a restrictive feature in any language. They prevent the programmer from writing a certain category of programs. This is often helpful, as it prevents a certain category of bugs, but it does mean that some bug-free programs are not allowed anymore. That is one of the fundamental trade-offs between statically and dynamically typed languages.


I showed you that it can be implemented in Haskell, and strongly suspect it can be implemented in Gleam as well. However, like I and @fap noted, this kind of problem is probably not a good fit for Gleam. Not because of restrictions on the languages, but because of idiomaticity.

It only looks easy to do in these languages because these languages are not in the habit of clearly stating assumptions ahead of time. My Haskell solution above and my Python solution (modulo str weirdness) are essentially the same.

I agree with everything @remlse writes above, but also fear it might leave one with a wrong impression of what static typing means. For some extra information on this, read e.g. «No, dynamic type systems are not inherently more open» and «Types as axioms, or: playing god with static types».


The way Python “works” on these data types is a whole lot weirder that it would seem at first glance. Python’s list is both a sequence type, and a container type. It does not really contain any of its member objects, rather it contains pointers to those objects. See this for some more details on what that means (and a nice related post on names), and some big gotchas in working with Python lists.

Chiming in to agree with Matthijs. It looks “easy” in Python, but that’s a trap. :smile:
My solution is quite similar to his, although I am both less efficient, since I do not use a generator, and less explicit by hiding my function call in the returned list comprehension.

Like the Java List class that fap references above, it is necessary in Python to type check the objects a Python list “contains” before one can operate on them. Unlike Java, this is considered par for the course in Python, due to its dynamic/ducktype nature. Python assumes you’ll check or guard for the types you are looking for - it won’t do it for you, which can lead to all sorts of runtime issues if you don’t program defensively.

1 Like