Haskell 与'有关的问题;刚性类型变量';在哈斯克尔的一间单间里
我正在努力更好地学习单子,并在哈斯克尔玩单子。我是这样定义单子的:Haskell 与'有关的问题;刚性类型变量';在哈斯克尔的一间单间里,haskell,monads,Haskell,Monads,我正在努力更好地学习单子,并在哈斯克尔玩单子。我是这样定义单子的: module TESTMonad where import Control.Monad newtype TEST i = TEST {getTEST :: ((i, Int), Int)} deriving (Show, Eq, Ord) instance Functor TEST where fmap f (TEST ((x,y), z)) = TEST ((f x, y), z) instance Appli
module TESTMonad where
import Control.Monad
newtype TEST i = TEST {getTEST :: ((i, Int), Int)} deriving (Show, Eq, Ord)
instance Functor TEST where
fmap f (TEST ((x,y), z)) = TEST ((f x, y), z)
instance Applicative TEST where
pure = return
tf <*> tx = tf >>= \f -> tx >>= \x -> return (f x)
instance Monad TEST where
return x = TEST ((x, 1), 1)
(TEST ((x, y), z)) >>= f = TEST ((plusOne a, b), c)
where
((a, b), c) = getTEST (f x)
plusOne :: Int -> Int
plusOne x = x+1
我清楚地知道我可能以错误的方式做了很多事情,但我不知道它们是什么。如有任何意见,将不胜感激。提前谢谢你 无法约束
Monad
实例。(>>=)
的类型必须为
Monad m => m a -> (a -> m b) -> m b
但是您的定义使用plusOne::Int->Int
,使类型
Monad m => m Int -> (Int -> m Int) -> m Int
您可以安全地将plusOne
应用于TEST
中包装的任何其他值,因为它们已经定义为Int
s
(>>=)
的定义不知道x
的类型可能是什么,调用方可以选择f
,因此它也不知道f x
的类型可能是什么。因此,除了按原样使用它,您无法真正使用它。是什么让您认为实现中的a
必须是Int
plusOne
仅将Int
作为参数。换句话说,您的Monad
实例必须与任何类型一起工作,但您的定义使用plusOne
,这要求它必须是Int
。即使将它放松到plusOne::Num a=>a->a
对您的Monad
实例来说仍然是太严格了。@Robin Zigmond True,但是如果我希望它是“Int”呢?在这种情况下,我应该如何定义monad测试并键入“testi”?@chepner是的,我以前试过,但没有成功。如果我希望monad只接受“Int”并使其类型更具体一点,我该怎么办;您所描述的不是aMonad
。但是这种类型与Applicative is```````()中的````类型不同:f(a->b)->f a->f b````!注意,其中一个是纯id v==v
。这意味着您必须保留右侧参数的“上下文”。换句话说,TEST((f,u),)TEST((x,y),z)=TEST((fx,y,z)
。结合pure x=TEST((x,1,1)
,我认为这构成了一个有效的Applicative
实例;我将把它作为一个练习来验证这个定义是否满足其他三个条件。
Monad m => m Int -> (Int -> m Int) -> m Int