I am working on a contract evaluator for a contract DSL I am writing. The contract DSL is based on Simon Peyton Jones financial combinators paper. I am relatively new to Haskell and monads and I am having problems with the state monad. As you can see below evalAll2 is recursively called until End is reached. I have three variables in the record ContractSt that are updated when evalC is called, people is the number of parties to the contract(identified by a unique int), balance is amount of money in the contract and the owner is the a person who owns the contract. A contract is evaluated like this:
bettingContract :: Contract
bettingContract
= until (Date (2018,12,13))
(cashIn 20 1
(cashIn 20 2
(time (Date (2018,12,15))
(pay 1 2 40 End)
End)
End)
End)
End
c1 = evalAll(bettingContract)
What I want the code to do is to output the Contract being evaluated, the "output" which is a message generated based the action of a particular and to show the values of the ContractSt after the contract has been evaluated. The main problem is that I get:
<interactive>:12:1: error:
* No instance for (Show
(Control.Monad.Trans.State.Lazy.StateT
ContractSt
Data.Functor.Identity.Identity
()))
arising from a use of `print'
when I try and evaluate a contract. I understand that I have to use evalState to return the final result (which is what I want), and that I'm not trying to create an instance for of show for () but returning the final state along with the contract, and the output is where I'm having the most difficulty.
data ContractSt = ContractSt {
people :: [Person], balance :: Money, owner :: Person } deriving (Show)
evalAll :: Contract -> (Contract, OP, State ContractSt ()
evalAll c = evalAll2 c [] initialState
evalAll2 :: Contract -> OP -> State ContractSt () -> (Contract, OP, State
ContractSt ()
evalAll2 c o s
| c == End = (c, o, s)
| otherwise = evalAll2 nc (o ++ no) ns
where
(nc, no,ns) = evalC c
Foofrom aState Foo ()?" Or is it how to turn a tuple(a,b,x)into a tuple(a,b,c)given a functionf :: x -> c? - that other guy