#!/usr/bin/envstack{- stack
--resolver lts-12.0
--install-ghc
script
--ghc-options -Werror
--ghc-options -Wall
--
-}--------------------------------------------------------------------------------{-# LANGUAGE Safe #-}--------------------------------------------------------------------------------moduleMain(main)where--------------------------------------------------------------------------------importControl.Arrow(first)importData.Bits(xor,(.&.))importData.List(sort)importData.Maybe(catMaybes)--------------------------------------------------------------------------------newtypeVerticesa=V(MapIntegera)newtypeEdges=E(MapInteger[Integer])dataDAGa=G(Verticesa)Edges---------------------------------------------------------------------------------- F U N C T I O N A L P E A R L S-- Red-Black Trees in a Functional Setting---- CHRIS OKASAKI-- School of Computer Science, Carnegie Mellon University-- 5000 Forbes Avenue, Pittsburgh, Pennsylvania, USA 15213-- (e-mail: cokasaki@cs.cmu.edu)-- Red-Black TreesdataColor=R|BdataTreea=L|TColor(Treea)a(Treea)instanceShowColorwhereshowR="Red"showB="Black"instanceShowa=>Show(Treea)whereshow=aux0whereauxlL=replicatel' '++"nil"auxl(Tcltxrt)=replicatel' '++showc++": "++showx++"\n"++replicaten' '++auxnlt++"\n"++replicaten' '++auxnrtwheren=l+1-- Simple Map OperationstypeMapka=Tree(k,a)empty::Mapkaempty=Lmember::Ordk=>k->Mapka->Maybeamember_L=Nothingmemberk(T_a(k',y)b)|k<k'=memberka|k==k'=Justy|k>k'=memberkbmember_(T__(_,_)_)=Nothinginsert::Ordk=>k->a->Mapka->Mapkainsertkvm=blk.aux$mwhereblk(T_ayb)=TBaybblk___________=error"Shouldn't be possible (insert -> blk)"auxL=TRL(k,v)Laux(Tcay@(k',_)b)|k<k'=balc(auxa)yb|k==k'=Tcayb|k>k'=balcay(auxb)aux___________=error"Shouldn't be possible (insert -> aux)"balB(TR(TRaxb)yc)zd=TR(TBaxb)y(TBczd)balB(TRax(TRbyc))zd=TR(TBaxb)y(TBczd)balBax(TR(TRbyc)zd)=TR(TBaxb)y(TBczd)balBax(TRby(TRczd))=TR(TBaxb)y(TBczd)balcaxb=TcaxbtoList::Mapka->[(k,a)]toListL=[ ]toList(T_axb)=toLista++[x]++toListb---------------------------------------------------------------------------------- FNV Hash---- http://isthe.com/chongo/tech/comp/fnv/#FNV-1afnv1a::(Showa)=>a->Integerfnv1a=foldl(\ax->((a`xor`x)*prm).&.bin)off.aux.showwhereaux=map(fromIntegral.fromEnum)prm=309485009821345068724781371off=144066263297769815596495629667062367629bin=340282366920938463463374607431768211455--------------------------------------------------------------------------------cartProd::[a]->[b]->[(a,b)]cartProdxsys=(,)<$>xs<*>ysvertices::Orda=>DAGa->[a]vertices(G(Vvs)_)=sort$mapsnd$toListvsedges::Orda=>DAGa->[(a,a)]edges(G(Vvs)(Ees))=reverse$sort$concat$map(uncurrycartProd)$map(first(:[]))$zipfstsswhere(xs,ys)=unzip$toListesfs=catMaybes$map(flipmembervs)xstss=mapcatMaybes$map(map$flipmembervs)ysnew::(Showa)=>a->DAGanewv=G(V$inserthsvvempty)(Eempty)wherehsv=fnv1avadd::(Eqa,Showa)=>[a]->a->DAGa->EitherString(DAGa)addpsv(G(Vvs)(Ees))=casememberhsvvsofJust_->Left"Vertex, is already in the graph"Nothing->ifall(/=Nothing)$map(flipmembervs)hspsthenRight$G(V$inserthsvvvs)(E$foldl(\aph->inserthsvpha)es[hsps])elseLeft"One of the parent vertices, doesn't exist"wherehsps=mapfnv1apshsv=fnv1av--------------------------------------------------------------------------------main::IO()main=putStrLn"# Example 1 (single neighbor): ">>(casedag1ofLeftmsg->putStrLnmsgRightg->(putStrLn$"vertices: "++(show$verticesg))>>(putStrLn$"edges: "++(show$edgesg)))>>putStrLn"">>putStrLn"# Example 2 (multiple neighbors, Wikipedia diagram): ">>(casedag2ofLeftmsg->putStrLnmsgRightg->(putStrLn$"vertices: "++(show$verticesg))>>(putStrLn$"edges: "++(show$edgesg)))wheredag1=foldl(\g(p,v)->g>>=addpv)xxswherex=Right$new1xs=take10$zip(map(:[])nat)$drop1natnat=1:map(+1)nat::[Integer]dag2=-- DAG example from Wikipedia:-- https://en.wikipedia.org/wiki/File:Topological_Ordering.svg(Right$new'a')>>=add['a']'b'>>=add['b']'c'>>=add['a']'d'>>=add['d']'e'>>=add['d']'f'>>=add['b','f']'g'>>=add['e','g']'h'