问题
This question is not a duplicate
A question with the same title already exists, but the answer only partially addressed it, in my opinion, and I am interested also in what it left unaswered.
Foreword
Real World Haskell proposes, in Chapter 3, page 58, the following definition for a binary tree datatype,
data Tree a = Node a (Tree a) (Tree a)
| Empty
deriving (Show)
which provides two constructors (for empty and non-empty Tree
s).
On the other hand, at page 60, an exercise challenges the reader to define the Tree
datatype by using a single constructor.
After several attempts, I came up with the same solution as the one linked above:
data Tree a = Node a (Maybe (Tree a)) (Maybe (Tree a)) deriving(Show)
What is unanswered in the linked question
The drawback of this definition is that it does not allow the instantiation of an empty Tree
, although it allows the instantiation of a Tree
with empty children through the following syntax:
Node 3 Nothing (Just (Node 2 Nothing Nothing))
I think that there's not much a better solution than the above, if not having a "standalone" empty tree is acceptable and the requirement is to use one constructor only.
Having some comment on the above statement would be nice; however, my main question is how can I define Tree
with one constructor such that I can instantiate an empty Tree
?
Now that I've written the question, I think that one possible answer is the following, of which I am not at all sure:
If a children being empty or not is encoded in whether it is costructed through Nothing
or Just (Node ...)
, pretty much the same holds for the whole tree (or root node), which can be indeed defined itself as a Nothing
or Just (Node ...)
; this is to say that with only one constructor, Nothing
is the way to instanciate an empty tree. (In other words, I'm just starting to think that this question is inherently "ill-formed". Notheless I'll post it, as I think I can learn something your comments/answers.)
Does the above make any sense?
A possible answer
A comment in the original question proposes the following solution
data Tree a = Tree (Maybe (a,Tree a,Tree a))
which (my understanding) allows to instantiate an emtpy tree by Node Nothing
, or a non-empty tree by Node (Just (value,child1,child2))
.
回答1:
Here's a hint: you can turn any n-ary constructor into a 1-ary one using a n-tuple type.
For instance, your tree type is isomorphic to the following one:
data Tree a = Node (a, Tree a, Tree a)
| Empty
I think you should now be able to turn this type into one which only involves one constructor.
回答2:
The answer of @chi alongside his comments says all, it could be done with either as:
data Tree a = T (Either () (a, Tree a, Tree a)) deriving Show
And an example of a tree is:
node1 = T $ Right ("data node 1", node2, node3)
node2 = T $ Left ()
node3 = T $ Right ("data node 3", node2, node2)
$> node1
T (Right ("data node 1",T (Left ()),T (Right ("data node 3",T (Left ()),T (Left ())))))
But everybody already also said, that can be replaced with Maybe, because Either ()
can be seen as Maybe a
来源:https://stackoverflow.com/questions/59312801/real-world-haskell-chapter-3-excercise-binary-tree-with-1-value-constructor-f