在Haskell中,我们知道如果我们有一些带有类型签名f
的函数f :: a -> a
,那么Haskell可以推断出以下类型:
f "alpha"
的类型为[Char]
;
f 1234
的类型为Num a => a
f Just
的类型为a -> Maybe a
等等。
参考以下代码,
在函数result_sm :: (Monad m) => a -> State m s a
中,我希望将类型变量m
推断为State s
。 State s
是Monad
类型类的实例,为什么它不起作用?
另外,关于Functor (StateM m s)
的实例声明,我知道编译器无法从ghc -inbuilt(自然/未覆盖)类型绑定的上下文Monad m
推导出Functor m
fmap
的签名。
同样,关于Applicative (StateM m s)
的实例声明,我知道编译器也不能从ghc -inbuilt(自然/未覆盖)绑定的上下文Monad m
推导出(Functor (StateM m s), Applicative m)
类型为pure
和<*>
的签名。
所以我的第二个问题如下:如何让编译器接受m
作为上述两个实例声明中Monad
类型类的实例,以及任何类似的实例声明?
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
module StateParser where
import Control.Monad
import Control.Applicative
newtype State s a = State {compute :: s -> (a, s)}
newtype StateM m s a = StateM {compute_M :: s -> m (a, s)}
result_s :: a -> State s a
result_s v = State (\s -> (v ,s))
bind_s :: State s a -> (a -> State s b) -> State s b
bind_s st f = State $ \s -> (\(v, s') -> compute (f v) s') (compute st s)
result_sm :: (Monad m) => a -> StateM m s a
result_sm v = StateM (\s -> result_s (v, s))
bind_sm :: (Monad m) => StateM m s a -> (a -> StateM m s b) -> StateM m s b
bind_sm stm f = StateM $ \s -> (tmp s >>= id)
where
tmp s = fmap (\(v, s') -> compute_M (f v) s') (compute_M stm s)
instance Functor (State s) where
fmap f st = st >>= (pure . f)
instance Applicative (State s) where
pure = result_s
p <*> q = p >>= \f ->
q >>= (pure . f)
instance Monad (State s) where
--Explicit return definition only required for code required to be compatible
--with GHC versions prior to 7.10. The default implementation for all GHC
--versions from 7.10 is
return = pure
(>>=) = bind_s
instance Functor m => Functor (StateM m s) where
fmap :: (Monad m) => (a -> b) -> StateM m s a -> StateM m s b
fmap f stm = stm `bind_sm` (result_sm . f)
instance Applicative m => Applicative (StateM m s) where
pure :: (Monad m) => a -> StateM m s a
pure = result_sm
(<*>) :: (Monad m) => StateM m s (a -> b) -> StateM m s a -> StateM m s b
p <*> q = p `bind_sm` \f ->
q `bind_sm` (pure . f)
instance Monad m => Monad (StateM m s) where
return = pure
(>>=) = bind_sm
以下是完整的编译器错误消息。有人(用户名:Bergi)希望看到它们。
StateParser.hs:29:29:
Couldn't match type `m' with `State s0'
`m' is a rigid type variable bound by
the type signature for result_sm :: Monad m => a -> StateM m s a
at StateParser.hs:28:14
Expected type: m (a, s)
Actual type: State s0 (a, s)
Relevant bindings include
result_sm :: a -> StateM m s a (bound at StateParser.hs:29:1)
In the expression: result_s (v, s)
In the first argument of `StateM', namely
`(\ s -> result_s (v, s))'
StateParser.hs:52:11:
Could not deduce (Monad m)
from the context (Functor m)
bound by the type signature for
fmap :: Functor m => (a -> b) -> StateM m s a -> StateM m s b
at StateParser.hs:52:11-63
Possible fix:
add (Monad m) to the context of
the type signature for
fmap :: Functor m => (a -> b) -> StateM m s a -> StateM m s b
When checking that:
forall (m :: * -> *) s.
Functor m =>
forall a b. Monad m => (a -> b) -> StateM m s a -> StateM m s b
is more polymorphic than:
forall (m :: * -> *) s.
Functor m =>
forall a b. (a -> b) -> StateM m s a -> StateM m s b
When checking that instance signature for `fmap'
is more general than its signature in the class
Instance sig: forall (m :: * -> *) s.
Functor m =>
forall a b. Monad m => (a -> b) -> StateM m s a -> StateM m s b
Class sig: forall (m :: * -> *) s.
Functor m =>
forall a b. (a -> b) -> StateM m s a -> StateM m s b
In the instance declaration for `Functor (StateM m s)'
StateParser.hs:56:11:
Could not deduce (Monad m)
from the context (Functor (StateM m s), Applicative m)
bound by the type signature for
pure :: (Functor (StateM m s), Applicative m) => a -> StateM m s a
at StateParser.hs:56:11-40
Possible fix:
add (Monad m) to the context of
the type signature for
pure :: (Functor (StateM m s), Applicative m) => a -> StateM m s a
When checking that:
forall (m :: * -> *) s.
(Functor (StateM m s), Applicative m) =>
forall a. Monad m => a -> StateM m s a
is more polymorphic than:
forall (m :: * -> *) s.
(Functor (StateM m s), Applicative m) =>
forall a. a -> StateM m s a
When checking that instance signature for `pure'
is more general than its signature in the class
Instance sig: forall (m :: * -> *) s.
(Functor (StateM m s), Applicative m) =>
forall a. Monad m => a -> StateM m s a
Class sig: forall (m :: * -> *) s.
(Functor (StateM m s), Applicative m) =>
forall a. a -> StateM m s a
In the instance declaration for `Applicative (StateM m s)'
StateParser.hs:59:12:
Could not deduce (Monad m)
from the context (Functor (StateM m s), Applicative m)
bound by the type signature for
(<*>) :: (Functor (StateM m s), Applicative m) =>
StateM m s (a -> b) -> StateM m s a -> StateM m s b
at StateParser.hs:59:12-75
Possible fix:
add (Monad m) to the context of
the type signature for
(<*>) :: (Functor (StateM m s), Applicative m) =>
StateM m s (a -> b) -> StateM m s a -> StateM m s b
When checking that:
forall (m :: * -> *) s.
(Functor (StateM m s), Applicative m) =>
forall a b.
Monad m =>
StateM m s (a -> b) -> StateM m s a -> StateM m s b
is more polymorphic than:
forall (m :: * -> *) s.
(Functor (StateM m s), Applicative m) =>
forall a b. StateM m s (a -> b) -> StateM m s a -> StateM m s b
When checking that instance signature for `<*>'
is more general than its signature in the class
Instance sig: forall (m :: * -> *) s.
(Functor (StateM m s), Applicative m) =>
forall a b.
Monad m =>
StateM m s (a -> b) -> StateM m s a -> StateM m s b
Class sig: forall (m :: * -> *) s.
(Functor (StateM m s), Applicative m) =>
forall a b. StateM m s (a -> b) -> StateM m s a -> StateM m s b
In the instance declaration for `Applicative (StateM m s)'
答案 0 :(得分:4)
编译器完成了它的工作。你的代码没有意义。
在Image
中,您尝试使用OnPointerUp
构建Cache-Control: public, max-age=0
,这是类型不匹配。你可能想要做的是
result_sm
由于StateM m s a
上有State s a
约束,因此您需要在result_sm :: (Monad m) => a -> StateM m s a
result_sm v = StateM (\s -> return (v, s))
的任何位置使用该约束,包括bind_sm
,{{1} {}}和Monad m
bind_sm
个Functor
个实例。因此,这些应该阅读
Applicative