So, I'm trying to get an example of GenProg working, a Haskell genetic programming library.
However, I'm getting various instance errors. My guess is that the example is written in slightly out-dated Haskell and just has to be minorly tweaked. The code makes sense, but I don't know enough about instances to easily rewrite it myself. I made a few tweaks.
Error:
genprogtest.hs:27:10: Could not deduce (MonadRandom-0.1.13:Control.Monad.Random.Class.MonadRandom (Rand StdGen)) arising from the superclasses of an instance declaration from the context (GenExpr E)
That is, the first line of the instance. (The actual example is here: https://hackage.haskell.org/package/genprog-0.1/docs/GenProg.html#9 )
{-# LANGUAGE DeriveDataTypeable, FlexibleInstances, FlexibleContexts, MultiParamTypeClasses #-}
-- Just put them in one line, yo~
import GenProg
import GenProg.GenExpr
import Data.Generics
import Control.Monad
import Control.Monad.Random
data E = Plus E E
| Minus E E
| Times E E
| Div E E
| Const Int
deriving (Typeable,Data,Eq,Show)
eval :: E -> Maybe Int
eval (Const c) = Just c
eval (Plus e1 e2) = liftM2 (+) (eval e1) (eval e2)
eval (Minus e1 e2) = liftM2 (-) (eval e1) (eval e2)
eval (Times e1 e2) = liftM2 (*) (eval e1) (eval e2)
eval (Div e1 e2) | ok = liftM2 div x1 x2
| otherwise = Nothing
where (x1,x2) = (eval e1,eval e2)
ok = x2 /= Just 0 && liftM2 mod x1 x2 == Just 0
instance (GenExpr E) => GenProg (Rand StdGen) E where
terminal = Const `liftM` getRandomR (1,9)
nonterminal = do
r <- getRandomR (0,3)
[liftM2 Plus terminal terminal,
liftM2 Minus terminal terminal,
liftM2 Times terminal terminal,
liftM2 Div terminal terminal] !! r
myFitness :: (GenProg.GenExpr.GenExpr E) => Int -> E -> Double
myFitness n e = error + size
where error = realToFrac $ maybe maxBound (abs . (n-)) (eval e)
size = (realToFrac $ nodes e) / 100