1

I am working on a problem set where I must write an arbitrary instance for binary search trees. Here is the code I've written so far:

data Tree e = E | N (Tree e) e (Tree e)

insert :: (Ord e) => e -> Tree e -> Tree e
-- assume this is implemented, so I can use it below

instance (Ord a, Arbitrary a) => Arbitrary (Tree a) where
    arbitrary :: Gen (Tree a)
    arbitrary = sized gen
      where
        gen :: Int -> Gen a
        gen n =
          frequency
            [
              (1, return E),
--                         vvvvvvvvv problematic vvvvvvvvvv
              (n, return $ insert (4::Int) (gen (n `div` 2)))
            ]

I'm unsure of how to get the second line of the frequency list to type check. I can see gen returns a Gen Tree and insert requires a Tree for its second argument, but I'm not sure how to restructure the code with that knowledge. It is required I use the insert function, however. Another problem is I need to get random element values, but I've put that aside for now and made every new element a 4 :: Int.

1 Answer 1

3

gen (n `div` 2) has type Gen (Tree a), so you should fmap that tree, so:

instance (Ord a, Arbitrary a) => Arbitrary (Tree a) where
    arbitrary = sized gen
      where gen n = frequency [
                (1, return E)
              , (n, insert <$> arbitrary <*> gen (n `div` 2))
              ]

This will thus generate an arbitrary value, then an arbitrary Tree with size n `div` 2, and then return the result of an insert with that arbitrary value for that arbitrary subtree.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.