There's an Idris exercise where the task is to extend a stack calculator program from supporting just addition to also supporting subtraction and multiplication. I tried to complete it by generalizing the functions that operate on the stack. However, I'm hit with a type error between my two central functions:
doOp : (Integer -> Integer -> Integer) ->
StackCmd () (S (S height)) (S height)
doOp f = do val1 <- Pop
val2 <- Pop
Push (f val1 val2)
tryOp : StackCmd () (S (S height)) (S height) ->
StackIO hinit
tryOp cmd {hinit = (S (S h))}
= do cmd
result <- Top
PutStr (show result ++ "\n")
stackCalc
doOp
is supposed to take a binary function and generate a sequence of actions that would apply it to that stack, while tryOp
takes in such a sequence of actions and integrates it into the the IO sequence.
The error is the following:
When checking an application of function Main.StackDo.>>=:
Type mismatch between
StackCmd () (S (S height)) (S height) (Type of cmd)
and
StackCmd () (S (S h)) (S height) (Expected type)
Specifically:
Type mismatch between
height
and
h
The functions are called like this:
Just Add => tryOp (doOp (+))
Just Subtract => tryOp (doOp (-))
Just Multiply => tryOp (doOp (*))
And that results in an error as well:
Can't infer argument height to tryOp, Can't infer argument height to doOp
The error messages seem simple enough to understand, but I don't know how to approach fixing them.
Additionally this is how StackIO
and bind are defined:
data StackIO : Nat -> Type where
Do : StackCmd a height1 height2 ->
(a -> Inf (StackIO height2)) -> StackIO height1
namespace StackDo
(>>=) : StackCmd a height1 height2 ->
(a -> Inf (StackIO height2)) -> StackIO height1
(>>=) = Do