
{- I'm writing code to do some combinatorial construction via test-and-evaluate algorithms. And I want to write a very generic algorithm. The idea is that the item being constructed has a current state, which is represented by a data type of typeclass EvalState. And the algorithm will consider a set of new elements to add to the object being constructed, represented by a data type of typeclass ElemSet. Here are the class definitions: -} class ElemSet a where elemSetNumElements :: a -> Int class EvalState s where isCompleteState :: s -> Bool newElemSet :: ElemSet a => s -> a integrateElem :: ElemSet a => a -> Int -> s -> s -- given an elem set, and an index of the elem to choose , compute a score scoreElem :: ElemSet a => a -> Int -> s -> EvalScore type EvalScore = Float type RandomnessChooser = [(EvalScore,Int)] -> ErrorRand Int {- here's my generic search algorithm written using the typeclasses the problem I'm having relates to the fact that I need to call 'integrateElem' which is a function in typeclass EvalState, and one of the arguments has the constraint of being of typeclass ElemSet, but I don't know how to put that constraint in. The specific error is "Ambigous type variable 'a' in the constraint: 'ElemSet a' arising from a use of 'integrateElem'" -} search :: (EvalState s) => RandomnessChooser -> s -> ErrorRand ssearch chooser state = do if isCompleteState state then return state else do let elemSet = newElemSet state n = elemSetNumElements elemSet scores = map g [0..n-1] g i = (scoreElem elemSet i state,i) chosenElemIdx <- chooser scores let newState = integrateElem elemSet chosenElemIdx state search chooser newState