{-# LANGUAGE EmptyDataDecls, MultiParamTypeClasses, FlexibleInstances,
FlexibleContexts, OverlappingInstances, UndecidableInstances #-}{-
The HList library
(C) 2004, Oleg Kiselyov, Ralf Laemmel, Keean Schupke
Result-type-driven operations on typeful heterogeneous lists.
-}moduleData.HList.HOccurswhereimportData.HList.FakePreludeimportData.HList.HListPrelude{-----------------------------------------------------------------------------}-- Zero or more occurrencesclassHOccursManyelwherehOccursMany::l->[e]instanceHOccursManyeHNilwherehOccursManyHNil=[]instance(HOccursManyel,HListl)=>HOccursManye(HConsel)wherehOccursMany(HConsel)=e:hOccursManylinstance(HOccursManyel,HListl)=>HOccursManye(HConse'l)wherehOccursMany(HCons_l)=hOccursManyl{-----------------------------------------------------------------------------}-- One or more occurrencesclassHOccursMany1elwherehOccursMany1::l->(e,[e])instance(HOccursManyel,HListl)=>HOccursMany1e(HConsel)wherehOccursMany1(HConsel)=(e,hOccursManyl)instance(HOccursMany1el,HListl)=>HOccursMany1e(HConse'l)wherehOccursMany1(HCons_l)=hOccursMany1l{-----------------------------------------------------------------------------}-- The first occurrenceclassHOccursFstelwherehOccursFst::l->einstanceHListl=>HOccursFste(HConsel)wherehOccursFst(HConse_)=einstance(HOccursFstel,HListl)=>HOccursFste(HConse'l)wherehOccursFst(HCons_l)=hOccursFstl{-----------------------------------------------------------------------------}-- One occurrence and nothing is leftclassHOccurselwherehOccurs::l->edataTypeNotFoundeinstanceFail(TypeNotFounde)=>HOccurseHNilwherehOccurs=undefinedinstance(HListl,HOccursNotel)=>HOccurse(HConsel)wherehOccurs(HConse_)=einstance(HOccursel,HListl)=>HOccurse(HConse'l)wherehOccurs(HCons_l)=hOccursl{-----------------------------------------------------------------------------}-- One occurrence and nothing is left-- A variation that avoids overlapping instancesclassHOccurs'elwherehOccurs'::l->einstance(TypeEqee'b,HOccursBoolbe(HConse'l))=>HOccurs'e(HConse'l)wherehOccurs'(HConse'l)=ewheree=hOccursBoolb(HConse'l)b=proxyEq(toProxye)(toProxye')classHOccursBoolbelwherehOccursBool::b->l->einstance(HListl,HOccursNotel)=>HOccursBoolHTruee(HConsel)wherehOccursBool_(HConse_)=einstance(HOccurs'el,HListl)=>HOccursBoolHFalsee(HConse'l)wherehOccursBool_(HCons_l)=hOccurs'l{-----------------------------------------------------------------------------}-- Zero or at least one occurrenceclassHOccursOptelwherehOccursOpt::l->MaybeeinstanceHOccursOpteHNilwherehOccursOptHNil=NothinginstanceHOccursOpte(HConsel)wherehOccursOpt(HConse_)=JusteinstanceHOccursOptel=>HOccursOpte(HConse'l)wherehOccursOpt(HCons_l)=hOccursOptl{-----------------------------------------------------------------------------}-- Class to test that a type is "free" in a type sequencedataTypeFoundeclassHOccursNotelinstanceHOccursNoteHNilinstanceFail(TypeFounde)=>HOccursNote(HConsel)instanceHOccursNotel=>HOccursNote(HConse'l){-----------------------------------------------------------------------------}classHProjectll'wherehProject::l->l'instanceHProjectlHNilwherehProject_=HNilinstance(HListl',HOccursel,HProjectll')=>HProjectl(HConsel')wherehProjectl=HCons(hOccursl)(hProjectl){-----------------------------------------------------------------------------}-- Illustration of typical test scenarios{-
Retrieve the Breed of an animal.
ghci-or-hugs> hOccurs myAnimal :: Breed
Cow
-}{-
Normal hOccurs requires specification of the result type even if the result
type is determined by the fact that we are faced with a singleton list.
ghci-or-hugs> hOccurs (HCons 1 HNil)
<interactive>:1:
No instance for (HOccurs e1 (HCons e HNil))
-}{-
However, hOccurs can be elaborated as improved as follows:
ghci-or-hugs> hLookup (HCons 1 HNil)
1
-}{-----------------------------------------------------------------------------}