0

Say for instance I want to make a list type that allows for flexible nesting like so:

[[['a'],'a'],'a']

Would it be possible to implement this in haskell? How would I go about writing it's type signature? Any help would be awesome!!!

Athan Clark
  • 3,886
  • 2
  • 21
  • 39

2 Answers2

2

You need to define your own datatype with different value constructors.

From ghci:

Prelude> data Val a = Val a | List [Val a] deriving (Show)
Prelude> [List [List [Val 'a']], Val 'a']
[List [List [Val 'a']],Val 'a']

And its type:

Prelude> :t [List [List [Val 'a']], Val 'a']
[List [List [Val 'a']], Val 'a'] :: [Val Char]

Also, checkout how JSON is represented in Real World Haskell: http://book.realworldhaskell.org/read/writing-a-library-working-with-json-data.html (search for data JValue to find the relevant data type)

DJG
  • 6,413
  • 4
  • 30
  • 51
2

This isn't a list so much as a tree. As such you can represent it with a tree data type. One example is the rose tree in containers, whose definition is approximately:

data Tree a = Node a [Tree a]

But maybe more suitable tree type in this case would be something like this (which is incidentally the free monad of []; the rose tree is the cofree comonad):

data Tree a = Leaf a | Node [Tree a]

Using this type you could represent your "list" like this, for example:

Node [Node [Node [Leaf 'a'], Leaf 'a'], Leaf 'a']
shachaf
  • 8,890
  • 1
  • 33
  • 51
  • Hmmm.... would it be possible to combine the definitions of Lists and the Tree to make the Tree a Monoid (So that `mempty` would be List's `Empty`)? – Athan Clark Jul 26 '13 at 20:04
  • I don't think I follow. If you're looking to get the syntax that you wrote above, that isn't really possible. If you want to make a `Monoid` instance for `Tree`, you can probably come up with something, but I'm not sure how it related to your question. If you want `[]` and `Tree` to be the same type, that's not possible. And there's nothing named `Empty` anywhere here. So I don't know what you mean. – shachaf Jul 26 '13 at 20:09
  • Sorry, I meant `Empty` as the value constructor from the `List` datatype explained in the LYAH book (Where `:` is replaced with `Cons`). Regardless, I think you're right, there's definitely a way to make `Tree` an instance of `Monoid`, but there's so many different ways to do it, it's not worth asking about haha. For instance, when defining `mappend` for two trees, how do they add up? Does the second tree become a child node of the lowest child of the first tree, or are they smushed together at each level of the heierarchy. Thank you for your feedback though! – Athan Clark Jul 26 '13 at 21:16