=head1 NAME Junc.pod - explanation of how Junc.hs works =head1 OVERVIEW I am a fledgling Haskell programmer having just finished reading YAHT. For some reason, I was attracted to understanding Junc.hs and so will document its workings. Junc.hs is the main code for implementing Perl6 Junctions: L =head1 HOW THE MODULE WORKS First we load in the C and the abstract syntax tree, C. The first thing to understand is how C works. It's just the first function in the file, but it is important, so let's get down to business. =head2 opJunc The type signature of this function is opJunc :: JuncType -> [Val] -> Val which means it takes a C and a list of type C and returns an element of type C. More properly this function returns an element of type VJunc, but you cannot specify that a function returns a subtype only a type. Here is it's definition. Let's understand it: opJunc :: JuncType -> [Val] -> Val opJunc t vals = VJunc $ Junc t emptySet (joined `union` mkSet vs) where joined = unionManySets $ map (\(VJunc s) -> juncSet s) js (js, vs) = partition sameType vals sameType (VJunc (Junc t' _ _)) = t == t' sameType _ = False =head3 sameType and partition C and C are defined by a call to C, which takes a list of elements and returns a list in which the first list is those elements which satisfied a predicate and the second list is those which failed. So, C turns out to be all elements which are the same as the type we passed in and C are the ones which are not the same type. How does C work? The call to sameType is using pattern matching. C, if you look in F, is part of some punnery being used in the C enumerated set type. VJunc is both a data constructor and it receives a parameter of type VJunc which is defined further down. Pattern matching the first element of a value of type VJunc extracts the type of the VJunct. If the two types are equal, then we have the same type. So now we understand 75% of the C clauses for C. Now for 100% closure on C let's understand C : =head3 joined joined = unionManySets $ map (\(VJunc s) -> juncSet s) js Well, we know that C is the list of values that are the same type of as the passed-in type. Now, this function: (\(VJunc s) -> juncSet s) might look a little funny but it's simple. We are pulling the C slot from a value (namely s) whose type is VJunct. In Perl5 you might do $s->{juncSet} for the same effect. So, all the map is doing is extracting the C fields from a list of values of type C. Then this list is passed to C: L which takes a list of Sets and turns them into a single set. Now that we know what each of the C clauses does for the main clause, let's understand the main clause: opJunc t vals = VJunc $ Junc t emptySet (joined `union` mkSet vs) in the context of a real call to it: opJuncAll = opJunc JAll =head2 isTotalJunc, isPartialJunc (in the context of ApplyArg) Both C and C operate on a single piece of data of type C. The C value slot must be of type C or either function will return False. C tests to see if the VJunc value slot is of type C or C. Note that unlike most tests which return C if their test passes, this function (and C) return the negation of the C slot. C tests to see if the VJunc value slot is of type C or C. It also returns the negation of the C slot if this test passes and False otherwise. =head1 TODO =head1 errata [20:58] it will take some used to at first [20:58] but the context will make it clear [20:58] cool with it? [20:59] juncSet is used for all junctions [20:59] yes [20:59] juncDup is only used for one() [20:59] the reason is that one() cannot be represent as one set [20:59] must use two sets. * autrijus said none() originally, but it should be one(). =head2 argsCollapsed =head1 AUTHOR metaperl with help from Cale, Igloo