I want to create my own monad. This is what i wrote:
data LeafConType a = LeafCon (a,Int,Int)
instance Monad (LeafConType ) where
return = LeafCon
lc@(LeafCon (t,i,n)) >>= f = if i>=n
then lc
else f (t,i,n)
But this dont work. Ghc says:
leafcon.hs:26:1:
Occurs check: cannot construct the infinite type: a = (a, Int, Int)
When generalising the type(s) for `return'
In the instance declaration for `Monad LeafConType'
leafcon.hs:27:1:
Occurs check: cannot construct the infinite type: a = (a, Int, Int)
When generalising the type(s) for `>>='
In the instance declaration for `Monad LeafConType'
Whats wrong with that?
I want to do calculations while i is lower than n. n should be constants by I don’t know yet how to do this correct. It should be some mix of State and Maybe. If you have some advices feel free to share it with me:P
About
return:So
returntakes an argument of typea, and returns something of typem a. In this casemisLeafConType, soLeafConType ais returned.Now suppose that we pass
True. Thena = Bool, so the return type must beLeafConType Bool. However, you define:So,
return TruebecomesLeafCon True. But that is not allowed, because the type definition ofLeafConTypestates thatSo for
LeafConType Boolthe argument toLeafConmust have type(Bool, Int, Int), not justBool. And that is what the compile error means:acannot be the same as(a, Int, Int). You state:This means that you will need some default values for
iandn, for otherwise it will be impossible to definereturn. If both of them are zero by default, then you could define:About
(>>=):Now look at your implementation (slightly different notation, same idea):
What we see here, is that
lcis returned wheni >= n. Butlcis of typeLeafConType a, whilefis a function which may return a value of typeLeafConType b, for anyb. As a result it could be thatbis not equal toaand hence these types don’t match. In conclusion, you seriously have to ask yourself one question:Can this type of computation be expressed as a monad anyway?