= NAME Junc.pod - explanation of how Junc.hs works = 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 Perl 6 Junctions: [http://dev.perl.org/perl6/synopsis/S09.html] = HOW THE MODULE WORKS First we load in the `Internals` and the abstract syntax tree, `AST`. The first thing to understand is how `opJunc` works. It's just the first function in the file, but it is important, so let's get down to business. == opJunc The type signature of this function is opJunc :: JuncType -> [Val] -> Val which means it takes a `JuncType` and a list of type `Val` and returns an element of type `Val`. 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 === sameType and partition `js` and `vs` are defined by a call to `partition`, which takes a list of elements and returns a pair of lists in which the first list is those elements which satisfied a predicate and the second list is those which failed. So, `js` turns out to be all elements which are the same as the type we passed in and `vs` are the ones which are not the same type. How does `sameType` work? The call to sameType is using pattern matching. `VJunc`, if you look in {file: AST.hs}, is part of some punnery being used in the `Val` 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 `where` clauses for `opJunc`. Now for 100% closure on `where` let's understand `joined` : === joined joined = unionManySets $ map (\(VJunc s) -> juncSet s) js Well, we know that `js` 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 `juncSet` 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 `juncSet` fields from a list of values of type `VJunc`. Then this list is passed to `unionManySets`: [http://www.haskell.org/ghc/docs/5.04.3/html/base/Data.Set.html#unionManySets] which takes a list of Sets and turns them into a single set. Now that we know what each of the `where` 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 == isTotalJunc, isPartialJunc (in the context of ApplyArg) Both `isTotalJunc` and `isPartialJunc` operate on a single piece of data of type `ApplyArg`. The `ApplyArg` value slot must be of type `VJunc` or either function will return False. `isTotalJunc` tests to see if the VJunc value slot is of type `JAll` or `JNone`. Note that unlike most tests which return `True` if their test passes, this function (and `isPartialJunc`) return the negation of the `argCollapsed` slot. `isPartialJunc` tests to see if the VJunc value slot is of type `JOne` or `JAny`. It also returns the negation of the `argCollapsed` slot if this test passes and False otherwise. = TODO = 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(). == argsCollapsed = AUTHOR metaperl with help from Cale, Igloo