【发布时间】:2017-01-04 21:31:06
【问题描述】:
在 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) 的实例声明,我知道编译器无法从Functor m 的上下文Functor m 中推断出fmap 的ghc 内置(自然/未覆盖)类型签名。
同样,关于Applicative (StateM m s) 的实例声明,我知道编译器也无法从(Functor (StateM m s), Applicative m) 的上下文(Functor (StateM m s), Applicative m) 中推断出pure 的ghc 内置(自然/未覆盖)类型签名绑定的Monad m和<*>。
所以我的第二个问题如下:我怎样才能让编译器接受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)'
【问题讨论】:
-
您遇到的编译器错误是什么?
-
我现在会在上面添加完整的错误消息。
-
"我希望推断类型变量 m" - 这不是它的工作原理。推断类型 a) 如果它们没有给出 b) 检查给定的类型的正确性。编译器错误告诉你类型是(非变量的)
State s0,但是你给了它变量m。 -
是的,但是
m是一个类型变量,而不是一个类型。这就是为什么我在开头包含信息和示例的原因。感谢您抽出宝贵时间发表评论/回答,但老实说,我不完全理解您的意思。 -
@chi。确实如此,我重新发布了这个问题并提供了更多细节,并最终得到了一个很好的答案,这要感谢 Bergi 和 Alec。另一个帖子被核弹了,被遗忘了。
标签: haskell types functional-programming monads template-haskell