On 09/02/13 15:08, Roman Cheplyaka wrote: > I don't think the question was about generating functions... > FWIW, both QuickCheck and SmallCheck generate functions. There was also > an interesting paper at the last ICFP by Koen related to this. > > But I think Tony is looking for some kind of a pattern here... > > Roman > > * Stephen Tetley <stephen.tet...@gmail.com> [2013-02-09 10:50:45+0000] >> I think GAST - the Clean equivalent of Quickcheck - generates >> functions. There are certainly quite a few papers by members of the >> Clean team documenting how they generate them. >> >> On 9 February 2013 07:07, Tony Morris <tonymor...@gmail.com> wrote: >> [...] >>> I hope I have phrased this in a way to make the point. I found it a bit >>> difficult to articulate and I do wonder (hope!) that others encounter >>> similar scenarios. Thanks for any tips! >> _______________________________________________ >> Haskell-Cafe mailing list >> Haskell-Cafe@haskell.org >> http://www.haskell.org/mailman/listinfo/haskell-cafe Yeah I am looking for a possible pattern. I am struggling to explain the problem. Perhaps some code will help.
This code compiles, however the function "problem" is the one I am looking for. There are two data structures here: 1) Op, which is a functor 2) FreeOp, which is a monad that arises from the Op functor (i.e. an instance of the free monad) There are some functions for demonstration: 1) productOp -- An example of zipping two FreeOp instances, just to show that you can (though, this is trivial by the monad) 2) booleanOp -- Produces a FreeOp Bool by using the IntOp constructor for Op 3) coproductOp -- An example of splitting out two FreeOp instances, to show this is possible too. * The question is, what about a function FreeOp b -> FreeOp (a -> b)? * Can I constrain the 'a' type variable somehow to come up with something similar to CoArbitrary (QuickCheck)? * Can I generalise this idea i.e. not just FreeOp? Or for CoArbitrary, not just for Gen? * Is there a pattern here that is currently not part of my mental tool kit? I am struggling to see it; maybe just it's not there. As always, thanks for any pointers! Begin code... data Op a = DoubleOp (Double -> a) | IntOp (Int -> a) data FreeOp a = Suspend (Op (FreeOp a)) | Point a ---- examples productOp :: FreeOp a -> FreeOp b -> FreeOp (a, b) productOp a b = do a' <- a b' <- b return (a', b') boolOp :: FreeOp Bool boolOp = Suspend (fmap Point (IntOp even)) coproductOp :: FreeOp a -> FreeOp b -> FreeOp (Either a b) coproductOp a b = boolOp >>= \p -> if p then fmap Left a else fmap Right b ---- The Problem problem :: -- ? c => -- ? other arguments FreeOp b -> FreeOp (a -> b) problem = error "what constraints on 'a' to allow an implementation of this function that uses the argument?" -- fmap const -- type-checks, but ignores the argument, unlike e.g. QuickCheck which uses CoArbitrary to "perturb" that result with the argument. ---- support libraries instance Functor Op where fmap f (DoubleOp g) = DoubleOp (f . g) fmap f (IntOp g) = IntOp (f . g) instance Functor FreeOp where fmap f = (=<<) (return . f) instance Monad FreeOp where return = Point Suspend o >>= f = Suspend (fmap (>>= f) o) Point a >>= f = f a -- Tony Morris http://tmorris.net/ _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe