Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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
GADTs打破了Haskell的等式推理吗_Haskell_Gadt - Fatal编程技术网

GADTs打破了Haskell的等式推理吗

GADTs打破了Haskell的等式推理吗,haskell,gadt,Haskell,Gadt,我有下面的解释器,它使用操作包中的ProgramT {-# LANGUAGE GADTs #-} import Control.Monad ((<=<)) import Control.Monad.Operational data Motor' a where --Define GADT serialNewportT :: (Monad m, MonadIO m) => ProgramT Motor' m a -> m a serialNewportT = eva

我有下面的解释器,它使用操作包中的ProgramT

{-# LANGUAGE GADTs #-}
import Control.Monad ((<=<))
import Control.Monad.Operational

data Motor' a where
  --Define GADT

serialNewportT :: (Monad m, MonadIO m) => ProgramT Motor' m a -> m a
serialNewportT = eval <=< viewT
  where
    eval :: (Monad m, MonadIO m) => ProgramViewT Motor' m v -> m v
    eval (Return x) = return x
    eval (x :>>= k) = f x >>= serialNewportT  . k

f :: (Monad m, MonadIO m) => Motor' a -> m a
f = undefined -- excluded for brevity
但是,此代码失败并显示错误消息

Couldn't match type ‘b’ with ‘c’
   ‘b’ is a rigid type variable bound by
       a pattern with constructor
         :>>= :: forall (instr :: * -> *) (m :: * -> *) a b.
                 instr b -> (b -> ProgramT instr m a) -> ProgramViewT instr m a,
       in an equation for ‘eval’
   ‘c’ is a rigid type variable bound by
       the type signature for
         serialNewportT :: (Monad m, MonadIO m) =>
                           (Motor' c -> m c) -> ProgramT Motor' m a -> m a
 Expected type: Motor' c
   Actual type: Motor' b

由于我只是将全局名称替换为同一类型的本地名称,我会认为它应该能够顺利工作。如何将类型作为参数与
f
统一?

您没有正确翻译f的类型。在原始代码中,
f
的类型为所有a的
。(..)=>电机'a->MA
。对于任何
a
,它都可以用类型
Motor'a
实例化,但在非工作代码中,您声明它的类型与
programmat Motor'ma
中的类型完全相同,而在函数体中,您对a
Motor'b
调用
f
(存在量化)键入
b

您只需要更高级别的类型:

serialNewportT :: (Monad m, MonadIO m) => (forall x . Motor' x -> m x) -> ProgramT Motor' m a -> m a

您没有正确翻译
f
的类型。在原始代码中,对于任何
a
,它可以用类型
Motor'a
实例化,但在非工作代码中,您声明它的类型与
ProgramT Motor'ma
中的类型完全相同,而在函数体中,您对
Motor'b
调用
f
(存在量化)类型
b
。您可能只需要更高级别的类型:
serialnewport::(Monad m,MonadIO m)=>(对于所有x.Motor'x->mx)->ProgramT Motor'm a->m a
@user2407038似乎是对meUgh的一个回答。我对作用域类型变量做了大量研究,试图使所有变量都匹配,但没有研究排名N的类型。我想是时候学习它们了。@user2407038,如果你想回答这个问题,我会给你学分。
serialNewportT :: (Monad m, MonadIO m) => (forall x . Motor' x -> m x) -> ProgramT Motor' m a -> m a