I continue to be utterly lost as to how to understand the source and ultimately the concrete foundation of this byzantine mass of constructs.
Example. In Lesson 4, in the Contract.hs module (and Trace.hs), there is a reference to EmulatorTrace. Where does that come from? How do I know if it is a Data, or a function? It has no type (using :t), yet it does have a type (* -> *, using :i). How can I study how it is built and what it does? The :i gives me info, but nothing actually useful. If I try to drill down into the components (are those data types, or are those functions? No way to know) I get more useless verbiage, or error messages.
What is freer-simple-1.2.1.2 ? Where does it come from? it's not anywhere in the code, although freer-extras is in the cabal.project file and plutus-pioneer-program-week04.cabal file. If I do a locate in my zsh shell, I find numerous nix/store files with freer-simple-1.2.1.1 in the title, but not with freer-simple-1.2.1.2. Why would that be? So much of this feels like magic fairy dust, or like being trapped under 40 tons of construction material blindfolded being told how to adjust a programmable thermostat before learning how to procure a construction screw.
The reason I ask is because if I am going to build code that manages thousands (or more!) of ADA, I need to understand how to build these things from scratch, and right now I can barely copy and paste and tweak a reference hoping it will compile.
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract> :t EmulatorTrace
<interactive>:1:1: error:
• Data constructor not in scope: EmulatorTrace
• Perhaps you meant variable ‘runEmulatorTrace’ (imported from Plutus.Trace.Emulator)
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract> :i EmulatorTrace
type EmulatorTrace :: * -> *
type EmulatorTrace =
freer-simple-1.2.1.2:Control.Monad.Freer.Internal.Eff
'[Plutus.Trace.Effects.RunContract.StartContract,
Plutus.Trace.Effects.RunContract.RunContract,
Plutus.Trace.Effects.Assert.Assert,
Plutus.Trace.Effects.Waiting.Waiting,
Plutus.Trace.Effects.EmulatorControl.EmulatorControl,
Plutus.Trace.Effects.EmulatedWalletAPI.EmulatedWalletAPI,
Control.Monad.Freer.Extras.Log.LogMsg String,
freer-simple-1.2.1.2:Control.Monad.Freer.Error.Error
EmulatorRuntimeError]
:: * -> *
-- Defined in ‘Plutus.Trace.Emulator’
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract> :i Plutus.Trace.Effects.RunContract.RunContract
type role Plutus.Trace.Effects.RunContract.RunContract nominal
type Plutus.Trace.Effects.RunContract.RunContract :: * -> *
data Plutus.Trace.Effects.RunContract.RunContract r where
Plutus.Trace.Effects.RunContract.CallEndpointP :: (Plutus.Trace.Effects.RunContract.ContractConstraints
s,
Plutus.Contract.Request.HasEndpoint l ep s,
aeson-1.5.6.0:Data.Aeson.Types.ToJSON.ToJSON
ep) =>
Data.Proxy.Proxy l -> ContractHandle w s e -> ep
-> Plutus.Trace.Effects.RunContract.RunContract ()
Plutus.Trace.Effects.RunContract.GetContractState :: (Plutus.Trace.Effects.RunContract.ContractConstraints
s,
aeson-1.5.6.0:Data.Aeson.Types.FromJSON.FromJSON
e,
aeson-1.5.6.0:Data.Aeson.Types.FromJSON.FromJSON
w,
aeson-1.5.6.0:Data.Aeson.Types.ToJSON.ToJSON
w) =>
ContractHandle w s e
-> Plutus.Trace.Effects.RunContract.RunContract (Plutus.Trace.Emulator.Types.ContractInstanceState
w
s
e
())
-- Defined in ‘Plutus.Trace.Effects.RunContract’
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract> :i freer-simple-1.2.1.2:Control.Monad.Freer.Internal.Eff
<interactive>:1:6: error: parse error on input ‘-’
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract> :i Control.Monad.Freer.Internal.Eff
<interactive>:1:1: error:
Not in scope: ‘Control.Monad.Freer.Internal.Eff’
Prelude Plutus.Trace.Emulator Data.Default Week04.Contract>
And yet the CLI seems to be perfectly logical and transparent and I have no doubt I can craft a complete billing system using other tools, built around the CLI. That's why I am so shocked that Plutus is so difficult.