9

In Haskell, is it possible to define a data type within a function scope?

For example, I am writing a function f :: [(Char, Int)] -> [(Char, String)]. In the implementation of the function, I will build a tree from the input list, and then traverse the tree to build the output list. One solution is to define a new Tree data type specific to my problem, along with two helper functions, one to translate the input list into the Tree and the other to walk the Tree and build the output list.

Now the two helper functions can easily be pulled into the scope of f by putting them into a where clause, but what about the interim nonce type Tree? It seems ugly to pollute the namespace by defining it outside the function scope, but I don't know how else to do it.

For context, it turns out I am computing a Huffman encoding. I am not particularly interested in finding an alternative algorithm at this point, as I suspect that it will often be useful in Haskell to define helper data types between helper functions, so I am interested in general approaches to this.

duplode
  • 33,731
  • 7
  • 79
  • 150
  • 12
    All datatype declarations must be at the top level. If you don't want to pollute the namespace, just don't export the datatype. – user2407038 Apr 27 '14 at 02:17
  • [This](http://stackoverflow.com/questions/15320391/proposal-for-local-data-declarations-instances) might be relevant. – is7s Apr 27 '14 at 13:07

1 Answers1

6

No, it's impossible.

In Haskell modules and qualified imports are supposed to resolve all namespacing problems, like yours or the notorious record field names collision.

So you want a type to be visible only to a certain function? Put that type and that function in a new module and (optionally) export just the function.

Sure, by following this convention you will end up with more modules than usual, but if you think about it, this is not actually that different from many other languages. E.g., in Java it's conventional to put each class in a separate file, no matter how small the class is.

I have to mention though that far from most people in the community actually follow this convention. You can often see cryptic names used to work around this. Personally I don't find such an approach very clean and would rather recommend using modules.

Nikita Volkov
  • 42,792
  • 11
  • 94
  • 169