{-# LANGUAGE PatternGuards #-}moduleData.Derive.DSL.Derive(derive)whereimportData.Derive.DSL.HSEimportData.Derive.DSL.DSLimportData.Derive.DSL.ApplyimportData.ListimportData.CharimportData.MaybedataGuess=GuessDSL|GuessFldIntDSL|GuessCtrIntBoolDSL-- 0 based index, does it mention CtorNamederivingShowctrNames=mapctorName$dataCtorssamplederive::Out->[DSL]derivex=[simplifyDSLy|Guessy<-guess$toOutputx]guess::Output->[Guess]guess(OApp"InstDecl"[OListctxt,name,typ,bod])|OApp"UnQual"[OApp"Ident"[OStringname]]<-name,OList[OApp"TyParen"[OApp"TyApp"[OApp"TyCon"[OApp"UnQual"[OApp"Ident"[OStringnam]]],OApp"TyVar"[OApp"Ident"[OStringvar]]]]]<-typ,nam==dataNamesample,ctxt<-[x|OApp"ClassA"[OApp"UnQual"[OApp"Ident"[OStringx]],_]<-ctxt]=[Guess$Instancectxtnamey|Guessy<-guessbod]guess(OListxs)=guessListxsguesso@(OAppopxs)=gssFoldo++gssAppo++map(lift(Appop))(guessListxs)guess(OStringx)|Justi<-findIndex(`isSuffixOf`x)ctrNames=[GuessCtriTrue$String(take(lengthx-length(ctrNames!!i))x)`append`CtorName]|"Sample"`isSuffixOf`x=[Guess$String(take(lengthx-6)x)`append`DataName]|otherwise=[lift(\d->append(String$initx)(ShowIntd))g|x/="",isDigit(lastx),g<-guess$OInt$read[lastx]]++[Guess$Stringx]guess(OInti)=[GuessFld(fromIntegeri)FieldIndex|i`elem`[1,2]]++[GuessCtr1FalseCtorIndex|i==1]++[GuessCtr1FalseCtorArity|i==2]++[Guess$Inti]guessx=error$show("fallthrough",x){-
First try and figure out runs to put them in to one possible option
Then try and figure out similarities to give them the same type
-}guessList::[Output]->[Guess]guessListxs=mapMaybesames$mapdiffs$sequence$mapguessxswhere-- Given a list of guesses, try and collapse them into one coherent guess-- Each input Guess will guess at a List, so compose with Concatsames::[Guess]->MaybeGuesssamesxs=dolet(is,fs)=unzip$mapfromGuessxsi<-maximisreturn$toGuessi$Concat$Listfs-- Promote each Guess to be a listdiffs::[Guess]->[Guess]diffs(GuessCtr0Truex0:GuessCtr1Truex1:GuessCtr2Truex2:xs)|f0x0==f0x1&&f2x2==f2x1=Guess(MapCtorx1):diffsxswherefix=applyEnvxenv{envInput=sample,envCtor=dataCtorssample!!i}diffs(GuessCtr2Truex2:GuessCtr1Truex1:GuessCtr0Truex0:xs)|f0x0==f0x1&&f2x2==f2x1=Guess(Reverse$MapCtorx1):diffsxswherefix=applyEnvxenv{envInput=sample,envCtor=dataCtorssample!!i}diffs(GuessFld1x1:GuessFld2x2:xs)|f1x1==f1x2=GuessCtr1False(MapFieldx2):diffsxswherefix=applyEnvxenv{envInput=sample,envField=i}diffs(GuessFld2x2:GuessFld1x1:xs)|f1x1==f1x2=GuessCtr1False(Reverse$MapFieldx2):diffsxswherefix=applyEnvxenv{envInput=sample,envField=i}diffs(x:xs)=liftboxx:diffsxsdiffs[]=[]gssFoldo@(OAppop[x,m,y])=fTrue(x:followTruey)++fFalse(y:followFalsex)wherefollowdir(OAppop2[a,m2,b])|op==op2&&m==m2=a2:followdirb2where(a2,b2)=ifdirthen(a,b)else(b,a)followdirx=[x]fdirxs|lengthxs<=2=[]fdirxs=map(liftg)$guess$OListxswhereg=Fold(Appop$List[h,fromOutm,t])(h,t)=ifdirthen(Head,Tail)else(Tail,Head)gssFold_=[]gssApp(OApp"App"[OApp"App"[x,y],z])=map(liftApplication)$guess$OList$fromAppx++[y,z]wherefromApp(OApp"App"[x,y])=fromAppx++[y]fromAppx=[x]gssApp_=[]lift::(DSL->DSL)->Guess->Guessliftfx=toGuessa(fb)where(a,b)=fromGuessxtypeGuessState=Maybe(EitherInt(Int,Bool))fromGuess::Guess->(GuessState,DSL)fromGuess(Guessx)=(Nothing,x)fromGuess(GuessFldix)=(Just(Lefti),x)fromGuess(GuessCtribx)=(Just(Right(i,b)),x)toGuess::GuessState->DSL->GuesstoGuessNothing=GuesstoGuess(Just(Lefti))=GuessFlditoGuess(Just(Right(i,b)))=GuessCtrib-- return the maximum element, if one existsmaxim::[GuessState]->MaybeGuessStatemaxim[]=JustNothingmaxim[x]=Justxmaxim(Nothing:xs)=maximxsmaxim(x:Nothing:xs)=maxim$x:xsmaxim(x1:x2:xs)|x1==x2=maxim$x1:xsmaxim(Just(Right(i1,b1)):Just(Right(i2,b2)):xs)|i1==i2=maxim$Just(Right(i1,maxb1b2)):xsmaxim_=Nothing