gat*_*ado 5 haskell type-inference typeclass ghc associated-types
问题.有没有办法让这个代码没有明确的类型签名?
代码.首先,我有一个实践中更好的替代MonadTrans课程,受到启发Data.Newtype.看起来像这样,
{-# LANGUAGE FlexibleContexts, TypeFamilies #-}
module Alt.Control.Monad.Trans where
import Control.Monad
class (Monad , Monad (BaseMonad )) => MonadTrans ( :: * -> *) where
type BaseMonad :: * -> *
lift :: (BaseMonad ) ? -> ?
Run Code Online (Sandbox Code Playgroud)
然后,我有一个A方法的类foo,如果一个基础monad M是一个A,那么任何转换的monad T M也是一个A.在代码中,
class A where
foo :: String -> ()
instance (A (BaseMonad ), MonadTrans ) => A where
foo n = lift $ foo n
Run Code Online (Sandbox Code Playgroud)
但是,如果我现在想要创建一个foo替换它的第一个参数的快捷方式,那么我需要一个显式类型签名,或者编译器的上下文堆栈溢出.
minimize_call :: A => ()
minimize_call = foo "minimize"
Run Code Online (Sandbox Code Playgroud)
可能的信息,以帮助推断.假设我们有一个相关的类型B :: * -> *.我在想,我要告诉编译器B满足B t /= t,B (B t) /= B t等等即B是某种"单调" -即追逐相关类型相当于消除NEWTYPE包装,它应该知道,它不能删除NEWTYPE永远的包装,因此加入A签名的上下文是必要的.
是的,有办法。提供 , 的基础实例A,并将其添加NoMonomorphismRestriction到语言编译指示中(除了还需要的FlexibleInstances和UndecidableInstances)。
但是,该类A将无法使用。编译器无法知道永远不会存在MonadTrans带有以下内容的实例BaseMonad m = m。因此,它永远无法选择实例,因为它不知道是使用此处的实例还是另一个实例。
{-# LANGUAGE FlexibleContexts, TypeFamilies, FlexibleInstances, UndecidableInstances, NoMonomorphismRestriction #-}\n\nmodule Trans (MonadTrans(..), A(..), minimize_call) where\n\nimport Control.Monad\n\nclass (Monad m, Monad (BaseMonad m)) => MonadTrans (m :: * -> *) where\n type BaseMonad m :: * -> *\n lift :: (BaseMonad m) \xce\xb1 -> m \xce\xb1\n\nclass A m where\n foo :: String -> m ()\n\n\ndata Foo a = Bork\n\ninstance Monad Foo where\n return _ = Bork\n _ >>= _ = Bork\n\ninstance A Foo where\n foo _ = Bork\n\n\ninstance (A (BaseMonad m), MonadTrans m) => A m where\n foo n = lift $ foo n\n\n-- minimize_call :: A m => m ()\nminimize_call = foo "minimize"\nRun Code Online (Sandbox Code Playgroud)\n\n使用 ghc 6.12、7.0、7.2 和 7.4 进行编译。没有签名,minimize_call必须得到单态类型,除非MR被关闭。无论如何这都是行不通的,因为约束A m是不可默认的。因此必须关闭 MR。但是类型检查器仍然追逐自己的尾巴,试图证明约束是可以满足的。仅使用举升实例,它不能。如果你提供一个锚点,它就可以。
但提供类型签名要好得多。
\n