[英]Problem with 'rigid type variable' in a Monad in haskell
我正在嘗試更好地學習單子,並在 Haskell 中使用它。 我以這種方式定義了一個 monad:
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
但是當我嘗試編譯它時出現以下錯誤:
TESTMonad.hs:16:47: error:
• Couldn't match expected type ‘Int’ with actual type ‘b’
‘b’ is a rigid type variable bound by
the type signature for:
(>>=) :: forall a b. TEST a -> (a -> TEST b) -> TEST b
at TESTMonad.hs:16:24
• In the first argument of ‘plusOne’, namely ‘a’
In the expression: plusOne a
In the expression: (plusOne a, b)
• Relevant bindings include
a :: b (bound at TESTMonad.hs:18:19)
f :: a -> TEST b (bound at TESTMonad.hs:16:28)
(>>=) :: TEST a -> (a -> TEST b) -> TEST b
(bound at TESTMonad.hs:16:5)
Failed, modules loaded: none.
我清楚地知道我可能以錯誤的方式做很多事情,但我不知道它們是什么。 任何評論將不勝感激。 先感謝您!
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
,所以它也不知道fx
可能是什么類型。 結果,除了按原樣使用它之外,您實際上無法對它做任何事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.