代码之家  ›  专栏  ›  技术社区  ›  danidiaz

在匹配此背包签名时,如何避免需要辅助新类型?

  •  2
  • danidiaz  · 技术社区  · 8 年前

    我正在使用新的背包模块系统和Cabal 2。我有以下签名:

    {-# LANGUAGE KindSignatures #-}
    signature Streamy where
    
    import Control.Monad
    import Control.Monad.Trans.Class
    import Control.Monad.IO.Class
    
    data Stream :: * -> (* -> *) -> * -> *
    
    instance Monad m => Functor (Stream o m)
    instance Monad m => Applicative (Stream o m)
    instance Monad m => Monad (Stream o m)
    instance MonadIO m => MonadIO (Stream o m) 
    instance MonadTrans (Stream o)
    

    Stream 键入自 streaming ,如下所示:

    import Streaming (Of(..))
    import qualified Streaming as Q
    
    type Stream o m r = Q.Stream (Of o) m r
    

    然而,这给了我一个错误

    抽象数据实现中的非法参数化类型同义词。

    o 坐在 Of Q.Stream .

    我可以通过定义适配器新类型来解决这个问题:

    {-# language GeneralizedNewtypeDeriving #-}
    newtype S o m r = S { unS :: Q.Stream (Of o) m r } 
            deriving (Functor,Applicative,Monad,MonadIO,MonadTrans)
    
    type Stream = S
    

    有没有其他不需要定义新类型的方法?

    1 回复  |  直到 8 年前
        1
  •  0
  •   danidiaz    7 年前

    似乎没有办法避免这种新类型。背包 thesis

    示例,类型 M a = a 不是抽象的有效实现 数据 M a type M = Maybe :: * -> * 是。这个限制源于 从Haskell中的旧设计决策到不支持类型级别 兰巴斯。这个限制极大地帮助了类型推断,因为 类型相等 t a = s b ,我们现在可以得出结论 t = s a = b

    同样相关的,在B.2节“挑战”中:

    半透明:背包14中不支持但在中支持的功能 Backpack17是使用类型同义词实现 抽象数据类型不透明,而实现未知, 我们对抽象类型一无所知 Str ; 实例化后, accept函数透明地接受 String

    推荐文章