我想创建自己的monad.这就是我写的:
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)
Run Code Online (Sandbox Code Playgroud)
但这不行.Ghc说:
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'
Run Code Online (Sandbox Code Playgroud)
那有什么不对吗?
当我低于n时,我想做计算.n应该是常数我还不知道如何做到这一点.它应该是State和Maybe的混合体.如果您有任何建议,请随时与我分享:P
Ste*_*202 12
return
:Prelude> :t return
return :: (Monad m) => a -> m a
Run Code Online (Sandbox Code Playgroud)
因此return
接受类型的参数a
,并返回类型的东西m a
.在这种情况下m
是LeafConType
,所以LeafConType a
返回.
现在假设我们通过了True
.那么a = Bool
,返回类型必须是LeafConType Bool
.但是,您定义:
return = LeafCon
Run Code Online (Sandbox Code Playgroud)
所以,return True
成为LeafCon True
.但这是不允许的,因为LeafConType
状态的类型定义
data LeafConType a = LeafCon (a, Int, Int)
Run Code Online (Sandbox Code Playgroud)
因此,LeafConType Bool
对于LeafCon
必须具有类型的参数(Bool, Int, Int)
,不仅仅是Bool
.这就是编译错误的含义:a
不能相同(a, Int, Int)
.你说:
我想在
i
低于的时候做计算n
.
这意味着你将需要一些默认值i
和n
,否则这将是无法界定的return
.如果默认情况下它们都为零,那么您可以定义:
return a = LeafCon (a, 0, 0)
Run Code Online (Sandbox Code Playgroud)
(>>=)
:Prelude> :t (>>=)
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)
现在看看你的实现(略有不同的表示法,相同的想法):
lc@(LeafCon (t, i, n)) >>= f | i >= n = lc
| otherwise = f t
Run Code Online (Sandbox Code Playgroud)
我们在这里看到的是,lc
当它返回时i >= n
.但lc
是类型的LeafConType a
,而f
是可以返回类型的值的函数LeafConType b
,对于任何 b
.因此,它可能b
不等于a
,因此这些类型不匹配.总之,你真的要问自己一个问题:
这种类型的计算是否可以表示为monad?
您指定的功能>>=
和return
不符合所要求的类型Monad
:
return :: a -> LeafConType a
Run Code Online (Sandbox Code Playgroud)
鉴于声明
return = LeafCon
Run Code Online (Sandbox Code Playgroud)
你赋予函数不兼容的类型
return :: (a, Int, Int) -> LeafConType a
Run Code Online (Sandbox Code Playgroud)
return 42
因此,你的monad中不可能有这样的陈述.
我不明白你的monad应该做什么.首先来看看简单,有效的monad!
instance Monad [] where
(>>=) = concatMap
return a = [a]
instance Monad Maybe where
return = Just
(Just x) >>= f = f x
Nothing >>= f = Nothing
Run Code Online (Sandbox Code Playgroud)