I understand basic type signatures like

myFunction :: Int -> String
myFunction a = "Always produce this string"

But in the week 5 lesson, in Free.hs (and similar in the other hs files), I see this type signature (with implementation)

mint :: MintParams -> Contract w FreeSchema Text ()
mint mp = do
    let val     = Value.singleton curSymbol (mpTokenName mp) (mpAmount mp)
        lookups = Constraints.mintingPolicy policy
        tx      = Constraints.mustMintValue val
    ledgerTx <- submitTxConstraintsWith @Void lookups tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx
    Contract.logInfo @String $ printf "forged %s" (show val)

It appears that the function produces multiple different outputs. I cannot reproduce this structure on my own using simple code such as

myAttempt :: Int -> String String
myAttempt a = "Make this" "Make that"

This causes the compiler to complain as follows

*JWB2> :l JWB2.hs
[1 of 1] Compiling JWB2             ( JWB2.hs, interpreted )

JWB2.hs:48:21: error:
    • Expected kind ‘* -> *’, but ‘String’ has kind ‘*’
    • In the type signature: myAttempt :: Int -> String String
48 | myAttempt :: Int -> String String
   |                     ^^^^^^^^^^^^^
Failed, no modules loaded.

Is this a capability added thru one of the LANGUAGE declarations? Or Plutus modules? A partial function? Unique to do blocks? Related to Monads?

Various searches have not provided an explanation, but I'm sure someone here can!

3 Answers 3


String is a type all by itself so that a type String String does not actually make sense.

However, you can return a tuple of values so that your function would be:

myAttempt :: Int -> (String, String)
myAttempt _a = ("Make this", "Make that")

I added the underscore to _a so that the compiler will not give an "unused parameter" warning.


I think you are misunderstanding the meaning of Contract w FreeSchema Text (). This is one single Contract type. w, FreeSchem, Text, and () are like parametrisation of the type.

  • That makes sense. But I tried to create parallel syntax using more common data types and my own defined data types and I generate syntax errors. Is this because Contract is a Monad?
    – XiTouch
    Feb 11, 2022 at 10:56

What about this example:

f :: Integer -> Maybe Integer
f x = if odd x then Nothing else Just x

Just like here you have Maybe a and you replace a with Integer, in your case you have the (rather complicated) type Contract w s e a where some of the type variables have been replaced with values.

You tried to do String String but String has no variables that you can replace with String - therefore the error about the appropriate kinds:

String :: *, i.e. String is a type, while Maybe :: * - * i.e. you get a type by applying Maybe to a type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.