{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}moduleYi.Prelude((<>),(++),-- consider scrapping this and replacing it by the above(=<<),(<=<),($!),Double,Binary,Char,Either(..),Endom,Eq(..),Fractional(..),Functor(..),IO,Initializable(..),Integer,Integral(..),Bounded(..),Enum(..),Maybe(..),Monad(..),Num(..),Ord(..),Read(..),Real(..),RealFrac(..),ReaderT(..),SemiNum(..),String,Typeable,commonPrefix,discard,dummyPut,dummyGet,every,findPL,focusA,fromIntegral,fst,fst3,groupBy',list,head,init,io,last,lookup,mapAdjust',mapAlter',mapFromFoldable,moduleControl.Applicative,moduleControl.Category,moduleData.Accessor,moduleData.Accessor.Monad.MTL.State,putA,getA,modA,moduleData.Bool,moduleData.Foldable,moduleData.Function,moduleData.Int,moduleData.Rope,moduleData.Traversable,moduleText.Show,moduleYi.Debug,moduleYi.Monad,nubSet,null,print,putStrLn,replicate,read,seq,singleton,snd,snd3,swapFocus,tail,trd3,undefined,unlines,when,writeFile-- because Data.Derive uses it.)whereimportPreludehiding(any,all)importYi.DebugimportYi.MonadimportText.ShowimportData.BoolimportData.BinaryimportData.FoldableimportData.Functionhiding((.),id)importqualifiedData.HashMap.StrictasHashMapimportData.Hashable(Hashable)importData.IntimportData.Rope(Rope)importControl.CategoryimportControl.Monad.ReaderimportControl.Applicativehiding((<$))importData.TraversableimportData.TypeableimportData.Monoid(Monoid,mappend)importqualifiedData.SetasSetimportqualifiedData.MapasMapimportqualifiedControl.Monad.State.ClassasCMSCimportqualifiedData.Accessor.BasicasAccessorimportData.Accessor((<.),accessor,getVal,setVal,Accessor,(^.),(^:),(^=))importqualifiedData.Accessor.Monad.MTL.StateasAccessor.MTLimportData.Accessor.Monad.MTL.State((%:),(%=))importqualifiedData.List.PointedListasPLtypeEndoma=a->a(<>)::Monoida=>a->a->a(<>)=mappendio::MonadIOm=>IOa->maio=liftIOfst3::(a,b,c)->afst3(x,_,_)=xsnd3::(a,b,c)->bsnd3(_,x,_)=xtrd3::(a,b,c)->ctrd3(_,_,x)=xclassSemiNumabsoluterelative|absolute->relativewhere(+~)::absolute->relative->absolute(-~)::absolute->relative->absolute(~-)::absolute->absolute->relativesingleton::a->[a]singletonx=[x]discard::Functorf=>fa->f()discard=fmap(const())-- 'list' is the canonical list destructor as 'either' or 'maybe'.list::b->(a->[a]->b)->[a]->blistnil_[]=nillist_cons(x:xs)=consxxs-- TODO: move somewhere else.-- | As 'Prelude.nub', but with O(n*log(n)) behaviour.nubSet::(Orda)=>[a]->[a]nubSetxss=fSet.emptyxsswheref_[]=[]fs(x:xs)=ifx`Set.member`sthenfsxselsex:f(Set.insertxs)xs-- | As Map.adjust, but the combining function is applied strictly.mapAdjust'::(Ordk)=>(a->a)->k->Map.Mapka->Map.MapkamapAdjust'f=Map.alterf'wheref'Nothing=Nothingf'(Justx)=letx'=fxinx'`seq`Justx'-- This works because Map is structure-strict, and alter needs to force f' to compute-- the structure.-- | As Map.alter, but the newly inserted element is forced with the map.mapAlter'::Ordk=>(Maybea->Maybea)->k->Map.Mapka->Map.MapkamapAlter'f=Map.alterf'wheref'arg=casefargofNothing->NothingJustx->x`seq`Justx-- This works because Map is structure-strict, and alter needs to force f' to compute-- the structure.-- | Generalisation of 'Map.fromList' to arbitrary foldables.mapFromFoldable::(Foldablet,Ordk)=>t(k,a)->Map.MapkamapFromFoldable=foldMap(uncurryMap.singleton)-- | Alternative to groupBy.---- > groupBy' (\a b -> abs (a - b) <= 1) [1,2,3] = [[1,2,3]]---- whereas---- > groupBy (\a b -> abs (a - b) <= 1) [1,2,3] = [[1,2],[3]]---- TODO: Check in ghc 6.12 release if groupBy == groupBy'.groupBy'::(a->a->Bool)->[a]->[[a]]groupBy'_[]=[]groupBy'pl=s1:groupBy'ps2where(s1,s2)=chainplchain::(a->a->Bool)->[a]->([a],[a])chain_[]=([],[])chain_[e]=([e],[])chainq(e1:es@(e2:_))|qe1e2=let(s1,s2)=chainqesin(e1:s1,s2)|otherwise=([e1],es)------------------------ Accessors support-- | Lift an accessor to a traversable structure. (This can be seen as a-- generalization of fmap)every::Traversablet=>Accessorwholepart->Accessor(twhole)(tpart)everya=accessor(fmap(getVala))(\partswholes->zipWithT(setVala)partswholes)-- | zipWith, generalized to Traversable structures.zipWithT::Traversablet=>(a->b->c)->ta->tb->tczipWithTftatb=resultwherestep[]_=Yi.Debug.error"zipT: non matching structures!"step(b:bs)a=(bs,fab)([],result)=mapAccumLstep(toListtb)ta-- | Return the longest common prefix of a set of lists.---- > P(xs) === all (isPrefixOf (commonPrefix xs)) xs-- > length s > length (commonPrefix xs) --> not (all (isPrefixOf s) xs)commonPrefix::Eqa=>[[a]]->[a]commonPrefix[]=[]commonPrefixstrings|anynullstrings=[]|all(==prefix)heads=prefix:commonPrefixtailz|otherwise=[]where(heads,tailz)=unzip[(h,t)|(h:t)<-strings]prefix=headheads-- for an alternative implementation see GHC's InteractiveUI module.---------------------- PointedList stuff-- | Finds the first element satisfying the predicate, and returns a zipper pointing at it.findPL::(a->Bool)->[a]->Maybe(PL.PointedLista)findPLpxs=go[]xswherego_[]=Nothinggols(f:rs)|pf=Just(PL.PointedListlsfrs)|otherwise=go(f:ls)rsfocusA::Accessor(PL.PointedLista)afocusA=accessorgettersetterwheregetter(PL.PointedList_x_)=xsettery(PL.PointedListx_z)=PL.PointedListxyz-- | Given a function which moves the focus from index A to index B, return a function which swaps the elements at indexes A and B and then moves the focus. See Yi.Editor.swapWinWithFirstE for an example.swapFocus::(PL.PointedLista->PL.PointedLista)->(PL.PointedLista->PL.PointedLista)swapFocusmoveFocusxs=focusA^=(xs^.focusA)$moveFocus$focusA^=(moveFocusxs^.focusA)$xs------------------------ Acessor stuffputA::CMSC.MonadStaterm=>Accessor.Tra->a->m()putA=Accessor.MTL.setgetA::CMSC.MonadStaterm=>Accessor.Tra->magetA=Accessor.MTL.getmodA::CMSC.MonadStaterm=>Accessor.Tra->(a->a)->m()modA=Accessor.MTL.modify-------------------- Initializable typeclass-- | The default value. If a function tries to get a copy of the state, but the state-- hasn't yet been created, 'initial' will be called to supply *some* value. The value-- of initial will probably be something like Nothing, \[\], \"\", or 'Data.Sequence.empty' - compare -- the 'mempty' of "Data.Monoid".classInitializableawhereinitial::ainstanceInitializable(Maybea)whereinitial=Nothing-- | Write nothing. Use with 'dummyGet'dummyPut::a->PutdummyPut_=return()-- | Read nothing, and return 'initial'. Use with 'dummyPut'.dummyGet::Initializablea=>GetadummyGet=returninitial----------------- Orphan 'Binary' instancesinstance(Eqk,Hashablek,Binaryk,Binaryv)=>Binary(HashMap.HashMapkv)whereputx=put(HashMap.toListx)get=HashMap.fromList<$>get