Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.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 GHC型推理的困境_Haskell_Ghc_Type Inference_Typeclass_Associated Types - Fatal编程技术网

Haskell GHC型推理的困境

Haskell GHC型推理的困境,haskell,ghc,type-inference,typeclass,associated-types,Haskell,Ghc,Type Inference,Typeclass,Associated Types,问题。有没有办法让这段代码在没有显式类型签名的情况下工作 代码。首先,实际上我有一个更好的MonadTrans替代类,灵感来自Data.Newtype。看起来是这样的, {-# LANGUAGE FlexibleContexts, TypeFamilies #-} module Alt.Control.Monad.Trans where import Control.Monad class (Monad Yes, there is a way. Provide a grounded ins

问题。有没有办法让这段代码在没有显式类型签名的情况下工作

代码。首先,实际上我有一个更好的MonadTrans替代类,灵感来自Data.Newtype。看起来是这样的,

{-# LANGUAGE FlexibleContexts, TypeFamilies #-}

module Alt.Control.Monad.Trans where

import Control.Monad

class (Monad Yes, there is a way. Provide a grounded instance for 
A
, and add
NoMonomorphismRestriction
to the language pragma (in addition to the also required
FlexibleInstances
and
UndecidableInstances
).

However, the
A
class will be unusable.
There is no way for the compiler to know that there never will be a
MonadTrans
instance with
BaseMonad m = m
. Thus it cannot select an instance, ever, because it cannot know whether to use the instance from here or another one.

{-# LANGUAGE FlexibleContexts, TypeFamilies, FlexibleInstances, UndecidableInstances, NoMonomorphismRestriction #-}

module Trans (MonadTrans(..), A(..), minimize_call) where

import Control.Monad

class (Monad m, Monad (BaseMonad m)) => MonadTrans (m :: * -> *) where
    type BaseMonad m :: * -> *
    lift :: (BaseMonad m) α -> m α

class A m where
    foo :: String -> m ()


data Foo a = Bork

instance Monad Foo where
    return _ = Bork
    _ >>= _ = Bork

instance A Foo where
    foo _ = Bork


instance (A (BaseMonad m), MonadTrans m) => A m where
    foo n = lift $ foo n

-- minimize_call :: A m => m ()
minimize_call = foo "minimize"
{LANGUAGE flexiblecontext,TypeFamilies-} 模块Alt.Control.Monad.Trans,其中 进口管制
是的,有一种方法。为提供固定实例,并将NomonomorphosmRestriction添加到语言pragma中,以及所需的FlexibleInstances和UndedicatableInstances

但是,A类将不可用。编译器无法知道永远不会有BaseMonad m=m的MonadTrans实例。因此,它永远无法选择实例,因为它不知道是从这里使用实例还是从另一个实例使用实例

使用ghc 6.12、7.0、7.2和7.4进行编译。如果没有签名,除非MR被关闭,否则minimize_调用必须获得单态类型。这无论如何都无法工作,因为约束am不是默认值。因此,必须关闭MR。但是,类型检查器仍然在追逐自己的尾巴,试图证明约束是可满足的。只有提升实例,它不能。如果你提供一个锚,它可以


但是提供一个类型签名要好得多。

对不起,我应该想一想为什么我会选择另一个MonadTrans。。。现在,让我们假设它产生了更干净的代码,但我认为还有一个更重要的原因。有趣的问题。为什么不需要显式类型签名呢?是不是最小化_调用必须是某个固定值,而不是多态常量,或者你可以让它成为多态的,我不确定?如果它有某个固定类型,我宁愿记录它,如果它没有,我宁愿记录它。强迫读者在头脑中进行整个程序分析,以找出minimize_调用的类型似乎有点适得其反。@Ben,在这种情况下,为minimize_调用提供类型签名是一种不错的做法。但是,类型推断被破坏表明设计、编译器或与编译器的通信出现了问题,可能会导致问题,更不用说无法理解的错误消息了。谢谢,但我不希望模块中有固定实例。事实上,可能有多个固定实例,这取决于我有多少后端到我的编译器,并且假设使用一个特定的实例是不可取的。我已经启用了FlexibleInstances、FlexibleContexts和NomonomogormismRestriction。您可以使用未导出的虚拟monad,请参阅更新。minimize_调用的推断类型是m=>m,应该是这样,它不排除在其他地方使用不同的固定实例,只需要让类型检查器终止。实际上,不,你不能使用minimize_调用,或者foo。有或没有类型签名。嗯,我来看看你的a将无法使用的断言。我已经成功地使用了这个模式,但是可能有一些细微的差别,或者我没有尝试让它在多个基本实例中运行。