我试图弄清楚为什么此代码示例中无法识别返回类型,请参见runnable code here。
{-# LANGUAGE TypeFamilies #-}
module Test where
import Control.Monad.IO.Class
import Control.Monad
import Control.Monad.Except
import Control.Exception
import Data.Typeable
import Control.Monad.State.Lazy
class Foo m where
type Inner m :: * -> *
bar :: Int -> m Int
instance (MonadIO w, Show s, Num s) => Foo (StateT s w) where
bar current = do
a <- get
return a -- error
-- return 24 -- ok
program :: StateT Int IO String
program = do
r <- bar 42
liftIO $ putStrLn $ "output= " ++ (show r)
return $ "ok"
run :: IO ()
run = do
(a, s) <- runStateT program $ 777
putStrLn $ (show a) ++ (show s)
错误消息如下所示,在我的情况下,MonadState s1 (StateT s1 m)
两个s1
都应为Int
,因此我不确定为什么不允许这样做。
• Couldn't match type ‘s’ with ‘Int’
arising from a functional dependency between:
constraint ‘MonadState Int (StateT s w)’
arising from a use of ‘get’
instance ‘MonadState s1 (StateT s1 m)’ at <no location info>
‘s’ is a rigid type variable bound by
the instance declaration
at fsm-try-5-3-q.hs:16:10-55
• In a stmt of a 'do' block: a <- get
In the expression:
do a <- get
return a
In an equation for ‘bar’:
bar current
= do a <- get
return a
答案 0 :(得分:1)
在定义Foo (StateT s w)
实例时,您并没有将s
约束为Int
,但想从bar
返回它。以后如何使用该实例无关紧要,因为该实例必须自己有效。
也许您想定义:
instance (MonadIO w) => Foo (StateT Int w) where
type Inner (StateT Int w) = w
bar current = do
a <- get
return a