也许是在签名类型中

时间:2015-09-28 00:11:37

标签: haskell

查看MaybeT

λ: import Monad.Trans
λ: import Monad.Trans.Maybe
λ: :t MaybeT
MaybeT :: m (Maybe a) -> MaybeT m a

MaybeT的签名中,m可以是任何更高级别的类型,即* -> *吗?

我正在尝试学习Monad变形金刚,所以我很好奇为什么m没有Monad的约束。

3 个答案:

答案 0 :(得分:4)

引用Learn You A Haskell

  

我们已经遇到的参数化类型的另一个示例是来自 Map k v Data.Map k 是地图中键的类型, v 是值的类型。这是类型参数非常有用的一个很好的例子。参数化的地图使我们能够从任何类型到任何其他类型的映射,只要键的类型是 Ord 类型类的一部分。如果我们定义了一个映射类型,我们可以在 data 声明中添加一个类型类约束:

data (Ord k) => Map k v = ...
     

但是,在Haskell中,永远不会在数据声明中添加类型类约束是一个非常强大的约定。为什么?好吧,因为我们没有受益很多,但我们最终写了更多的类约束,即使我们不需要它们。如果我们在 Ord k 数据声明中放入或不放置 Map k v 约束,我们就是必须将约束放入假设地图中的键可以被排序的函数中。但是如果我们不将约束放在数据声明中,我们就不必将 (Ord k) => 放在函数的类型声明中,而不关心是否可以对键进行排序或不。这种函数的一个示例是 toList ,它只需要一个映射并将其转换为关联列表。它的类型签名是 toList :: Map k a -> [(k, a)] 。如果 Map k v 在其数据声明中有类型约束,则 toList 的类型必须 toList :: Ord k => Map k a -> [(k, a)] ,即使该功能没有按顺序对键进行任何比较。

     

所以不要将类型约束放入 data 声明中,即使它似乎有意义,因为你必须将它们放入函数类型声明中。

我希望能回答你的问题。虽然m中的MaybeT m a不受约束,但隐含的假设mMonad的实例。实际上,如果m不是Monad的实例,那么您将无法对MaybeT m a值执行太多操作,因为大多数函数都要求mMonad customUserAgent的实例。

答案 1 :(得分:3)

  

MaybeT的签名中,m可以是任何更高级别的类型,即* -> *吗?

没有

> :k MaybeT
MaybeT :: (* -> *) -> * -> *

因此,m 类型中的MaybeT m a必须完全属于* -> *种类,而不是任何其他种类。

例如,请注意下面的类型错误:

> :k MaybeT (State Int)
MaybeT (State Int) :: * -> *

> :k MaybeT State
    Expecting one more argument to ‘State’
    The first argument of ‘MaybeT’ should have kind ‘* -> *’,
      but ‘State’ has kind ‘* -> * -> *’
    In a type in a GHCi command: MaybeT (State)

答案 2 :(得分:2)

  

from multiprocessing.dummy import Pool # use threads def download(name): urlretrieve("https://en.wikipedia.org/w/api.php?" "action=query&prop=revisions&rvprop=content&format=json&" "titles=" + quote(name.encode('utf-8')), os.path.join('json', name + '.json')) pool = Pool(4) # download 4 titles concurrently for _ in pool.imap_unordered(download, mergel, chunksize=100): pass 可以是任何更高级别的类型,即m

它可以是任何类型的* -> *。除此之外,原则上没有限制。

  

为什么* -> *没有m的约束。

约束是通过使用Monad的函数类型提供的,而不是通过MaybeT构造函数。除非涉及GADT,否则向构造函数添加约束是没有用的(我相信 transformers 为了简单和符合标准而不使用GADT)。有关约束和数据类型声明的额外注释,请参阅this question and its answers