定义类型类时,类型变量不在范围内

时间:2015-09-17 12:27:34

标签: haskell typeclass

我正在写一个类型级别的la mtl-style变形金刚。看起来像这样:

class (Monad m, Stream s m t) => MonadStuff s m | m -> s where
  -- function signatures go here…

我试图说m应该是Monad的实例 应该是Stream s m t的实例,其中t并不重要 sm位于定义的右侧(=>之后)。

哈斯克尔说:

  

不在范围内:输入变量't'

所以,显然我做不到。或者我可以吗?我应该删除Stream s m t 约束并将其添加到类中的每个函数中,或者存在 另一种方式?

1 个答案:

答案 0 :(得分:3)

如果确实t并不重要,那么也许你可以让编写实例的人选择它:

{-# LANGUAGE TypeFamilies #-}
class (Monad m, Stream s m (StuffType m)) => MonadStuff s m | m -> s where
    type StuffType m

或者,既然你已经开启了MPTC和fundeps,你可以考虑这样做,这不需要额外的扩展,但基本相同:

class (Monad m, Stream s m t) => MonadStuff s m t | m -> s t where

但是,我怀疑t 的选择确实很重要:除非Stream的fundep至少与m s -> t一样有用,您将无法以有意义的方式使用此约束。在这种情况下,您应该将约束移动到提及t或将使用Stream方法的方法的签名中。