Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 类型族-无法';t匹配类型_Haskell_Type Families - Fatal编程技术网

Haskell 类型族-无法';t匹配类型

Haskell 类型族-无法';t匹配类型,haskell,type-families,Haskell,Type Families,我被收到的这个编译器错误消息弄糊涂了。addAgent和withAgent函数具有类似的类型签名和类似的实现,因此我不明白为什么addAgent会编译,而withAgent不会。提前感谢您的帮助 {-# LANGUAGE TypeFamilies, FlexibleContexts #-} import Control.Monad.IO.Class (liftIO) import Control.Monad.State (StateT, execStateT, gets, modify) c

我被收到的这个编译器错误消息弄糊涂了。addAgent和withAgent函数具有类似的类型签名和类似的实现,因此我不明白为什么addAgent会编译,而withAgent不会。提前感谢您的帮助

{-# LANGUAGE TypeFamilies, FlexibleContexts #-}

import Control.Monad.IO.Class (liftIO)
import Control.Monad.State (StateT, execStateT, gets, modify)

class AgentDatabase d where
  type Elem d
  addAgent :: Elem d -> StateT d IO ()
  withAgent :: 
     (Elem d -> StateT d IO (Elem d)) -> String -> StateT d IO ()

data SimpleUniverse d = SimpleUniverse {
    agentDB :: d
    -- plus other fields
  }

-- I want the methods of class AgentDatabase to "penetrate" through
-- the outer wrapper of SimpleUniverse and operate on the agentDB field.
instance (AgentDatabase d) => 
    AgentDatabase (SimpleUniverse d) where
  type Elem (SimpleUniverse d) = Elem d

  -- When addAgent is invoked on a SimpleUniverse, apply it to the
  -- agentDB field inside.
  addAgent a = do
    db <- gets agentDB
    db' <- liftIO $ execStateT (addAgent a) db
    modify (\u -> u { agentDB=db' } )

  -- When withAgent is invoked on a SimpleUniverse, apply it to the
  -- agentDB field inside.
  withAgent program name = do
    db <- gets agentDB
    db' <- liftIO $ execStateT (withAgent program name) db -- line 33
    modify (\u -> u { agentDB=db' } )
{-#语言类型族,灵活上下文}
导入控制.Monad.IO.Class(liftIO)
import Control.Monad.State(StateT、execStateT、get、modify)
类AgentDatabase d,其中
d型元素
addAgent::Elem d->StateT d IO()
代理人::
(Elem d->StateT d IO(Elem d))->String->StateT d IO()
数据SimpleUniverse d=SimpleUniverse{
agentDB::d
--加上其他领域
}
--我希望类AgentDatabase的方法“渗透”到
--SimpleUniverse的外部包装器,并在agentDB字段上进行操作。
实例(代理数据库d)=>
AgentDatabase(SimpleUniverse d)其中
类型Elem(SimpleUniverse d)=Elem d
--在SimpleUniverse上调用addAgent时,将其应用于
--内部的agentDB字段。
addAgent a=do
db s'
在“Control.Monad.State.Class”中的实例声明中
Control.Monad.State.Class.MonadState
(SimpleUniverse(SimpleUniverse d))(StateT(SimpleUniverse d)IO),
由在amy3使用“get”引起的。hs:33:11-14

在“do”块的stmt中:db
程序
具有类型

Elem (SimpleUniverse d) -> StateT (SimpleUniverse  d) IO (Elem (SimpleUniverse d))
这确实简化了,但是

Elem d -> StateT (SimpleUniverse d) IO (Elem d)
而带有代理的内部
接受类型为的程序

Elem d -> StateT d IO (Elem d)
要解决此问题,此函数将有助于:

stateMap :: Monad m => (s -> t) -> (t -> s) -> StateT s m a -> StateT t m a
stateMap f g (StateT h) = StateT $ liftM (fmap f) . h . g

当您使用代理将
程序传递到内部
时,需要修复
程序
。我不确定是否理解。在
AgentDatabase
类中,
program
参数的类型为
Elem d->StateT d IO(Elem d)
。当我声明
SimpleUniverse
AgentDatabase
的实例时,我声明
SimpleUniverse
使用与其包含的数据库(
agentDB
)相同的
Elem
类型。那么
程序
是否已经有了正确的类型?啊,我现在明白了问题所在,谢谢。但现在我想不出如何解决这个问题。我试图用签名
f::StateT(SimpleUniverse d)IO(Elem d)->StateT d IO(Elem d)
编写一个函数,但我不知道如何编写它。我添加了
stateMap
函数,希望能有所帮助。
stateMap :: Monad m => (s -> t) -> (t -> s) -> StateT s m a -> StateT t m a
stateMap f g (StateT h) = StateT $ liftM (fmap f) . h . g