{- | Implement clustering
-}moduleBio.ClusteringwhereimportqualifiedData.SetasSimportData.List(partition,foldl')-- | Data structure for storing hierarchical clustersdataClusteredscoredatum=Branchscore(Clusteredscoredatum)(Clusteredscoredatum)|LeafdatumderivingShow-- | Single linkage agglomerative clustering.-- Cluster elements by slurping a sorted list of pairs with score (i.e. triples :-)-- Keeps a set of contained elements at each branch's root, so O(n log n),-- and requires elements to be in Ord.-- For this to work, the triples must be sorted on score. Earlier scores in the list will-- make up the lower nodes, so sort descending for similarity, ascending for distance.cluster_sl::(Orda,Ords)=>[(s,a,a)]->[Clusteredsa]cluster_sl=mapfst.foldl'csl[]wherecslcs(s,a,b)=-- can be short circuited for more performancelet(acs,tmp)=partition(\(_,objs)->a`S.member`objs)cs(bcs,rest)=partition(\(_,objs)->b`S.member`objs)tmpincase(acs,bcs)of([(ac,ao)],[(bc,bo)])->(Branchsacbc,S.unionaobo):rest([(ac,ao)],[])->ifb`S.member`aothen(ac,ao):restelse(Branchsac(Leafb),S.insertbao):rest([],[(bc,bo)])->ifa`S.member`bothen(bc,bo):restelse(Branchsbc(Leafa),S.insertabo):rest([],[])->(Branchs(Leafa)(Leafb),S.fromList[a,b]):rest_->error"Grave mistake"-- cluster_gen :: [a] -> (a->a->Bool) ->