user5610: Spoiler Alert!
The solution for lesson 3 includes the following:

{-# INLINABLE mkValidator #-}
-- This should validate if either beneficiary1 has signed the transaction and the current slot is before or at the deadline
-- or if beneficiary2 has signed the transaction and the deadline has passed.
mkValidator :: VestingDatum -> () -> ScriptContext -> Bool
mkValidator dat () ctx
    | (unPaymentPubKeyHash (beneficiary1 dat) `elem` sigs) && (to       (deadline dat) `contains` range) = True
    | (unPaymentPubKeyHash (beneficiary2 dat) `elem` sigs) && (from (1 + deadline dat) `contains` range) = True
    | otherwise = False
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx
sigs :: [PubKeyHash]
sigs = txInfoSignatories info

range :: POSIXTimeRange
range = txInfoValidRange info


It appears that " txInfoSignatories " is a function (functor?) that analyzes " info " which itself is drawn from the script context, but I am at a loss as to where the " txInfoSignatories " code actually comes from. Is there a way to analyze which imported module it is attached to? Is there a way to analyze its code in order to understand what it does? Much of what I am seeing in Haskell seems so opaque, with new features simply appearing and magically doing something, but I am lost as to how I could have analyzed the code/modules/options and come up with this solution on my own.
For the record, here is what I created before I looked at the solution. It compiles without error, but does not behave in the playground as intended.

{-# INLINABLE mkValidator #-}
-- This should validate if either beneficiary1 has signed the transaction and the current slot is before or at the deadline
-- or if beneficiary2 has signed the transaction and the deadline has passed.
mkValidator :: VestingDatum -> () -> ScriptContext -> Bool
-- mkValidator _ _ _ = False -- FIX ME!
mkValidator dat () ctx = 
     ( traceIfFalse "beneficiary 1 - signature missing" signedByBeneficiary1 
    && traceIfFalse "deadline 1 has passed" deadline1Reached )
    || (traceIfFalse "beneficiary 2 - signature missing" signedByBeneficiary2 
    && traceIfFalse "deadline 2 not reached" deadline2Reached )
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx
signedByBeneficiary1 :: Bool
signedByBeneficiary1 = txSignedBy info $ unPaymentPubKeyHash $ beneficiary1 dat

signedByBeneficiary2 :: Bool
signedByBeneficiary2 = txSignedBy info $ unPaymentPubKeyHash $ beneficiary2 dat

deadline1Reached :: Bool
deadline1Reached = contains (to $ deadline dat) $ txInfoValidRange info
deadline2Reached :: Bool
deadline2Reached = contains (from $ deadline dat) $ txInfoValidRange info


Any Haskell wisdom is much appreciated. I feel like this is more a Haskell knowledge deficit than anything else.

user2477: TxInfo is a Record type and one of the fields of the TxInfo-record is txInfoSignatories. The fields in the records work as "getters". You may refer e.g. to learnyouhaskell-records for an example.
The whole definition for TxInfo is here:

It is also completely fine to use the txSignedBy helper function as you have done to check whether the given hash is one of the signatories.

5610: <p>Spoiler Alert!</p>
<p>The solution for lesson 3 includes the following:</p>
<blockquote><pre>
{-# INLINABLE mkValidator #-}
-- This should validate if either beneficiary1 has signed the transaction and the current slot is before or at the deadline
-- or if beneficiary2 has signed the transaction and the deadline has passed.
mkValidator :: VestingDatum -> () -> ScriptContext -> Bool
mkValidator dat () ctx
    | (unPaymentPubKeyHash (beneficiary1 dat) `elem` sigs) && (to       (deadline dat) `contains` range) = True
    | (unPaymentPubKeyHash (beneficiary2 dat) `elem` sigs) && (from (1 + deadline dat) `contains` range) = True
    | otherwise = False
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx
<pre><code>sigs :: [PubKeyHash]
sigs = txInfoSignatories info

range :: POSIXTimeRange
range = txInfoValidRange info
</code></pre>
<p></pre></blockquote></p>
<p>It appears that &quot; txInfoSignatories &quot; is a function (functor?) that analyzes &quot; info &quot; which itself is drawn from the script context, but I am at a loss as to where the &quot; txInfoSignatories &quot; code actually comes from. Is there a way to analyze which imported module it is attached to? Is there a way to analyze its code in order to understand what it does? Much of what I am seeing in Haskell seems so opaque, with new features simply appearing and magically doing something, but I am lost as to how I could have analyzed the code/modules/options and come up with this solution on my own.</p>
<p>For the record, here is what I created before I looked at the solution. It compiles without error, but does not behave in the playground as intended.</p>
<blockquote><pre>
{-# INLINABLE mkValidator #-}
-- This should validate if either beneficiary1 has signed the transaction and the current slot is before or at the deadline
-- or if beneficiary2 has signed the transaction and the deadline has passed.
mkValidator :: VestingDatum -> () -> ScriptContext -> Bool
-- mkValidator _ _ _ = False -- FIX ME!
mkValidator dat () ctx = 
     ( traceIfFalse "beneficiary 1 - signature missing" signedByBeneficiary1 
    && traceIfFalse "deadline 1 has passed" deadline1Reached )
    || (traceIfFalse "beneficiary 2 - signature missing" signedByBeneficiary2 
    && traceIfFalse "deadline 2 not reached" deadline2Reached )
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx
<pre><code>signedByBeneficiary1 :: Bool
signedByBeneficiary1 = txSignedBy info $ unPaymentPubKeyHash $ beneficiary1 dat

signedByBeneficiary2 :: Bool
signedByBeneficiary2 = txSignedBy info $ unPaymentPubKeyHash $ beneficiary2 dat

deadline1Reached :: Bool
deadline1Reached = contains (to $ deadline dat) $ txInfoValidRange info
deadline2Reached :: Bool
deadline2Reached = contains (from $ deadline dat) $ txInfoValidRange info
</code></pre>
<p></pre></blockquote>
Any Haskell wisdom is much appreciated. I feel like this is more a Haskell knowledge deficit than anything else.</p>
 2477: <p><code>TxInfo</code> is a Record type and one of the fields of the <code>TxInfo</code>-record is <code>txInfoSignatories</code>. The fields in the records work as &quot;getters&quot;. You may refer e.g. to <a href="http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-syntax" rel="nofollow noreferrer">learnyouhaskell-records</a> for an example.</p>
<p>The whole definition for <code>TxInfo</code> is here:</p>
<p><a href="https://i.stack.imgur.com/vvRNk.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/vvRNk.png" alt="TxInfo" /></a></p>
<p>It is also completely fine to use the <code>txSignedBy</code> helper function as you have done to check whether the given hash is one of the signatories.</p>
