首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函子的Haskell型推理

函子的Haskell型推理
EN

Stack Overflow用户
提问于 2015-08-19 05:24:29
回答 1查看 115关注 0票数 8

最近我一直在玩Haskell,特别是整个函子的概念。我投入的越多,我得到的时间就越多,而且我的多巴胺受体也会很痒。

我遇到的问题是以下几点。下面是工作的代码,它解除函数,然后将其应用于IO值,然后应用于列表。

代码语言:javascript
复制
replicator1 =
  fmap (replicate 3)

replicator2 =
  fmap (replicate 3)

main = do
  replicated <- replicator1 getLine
  print (replicator2 replicated)

用一种更简洁的方式写出它是非常诱人的,即:

代码语言:javascript
复制
replicator =
  fmap (replicate 3)

main = do
  replicated <- replicator getLine
  print (replicator replicated)

我的一部分说这在概念上是正确的,因为replicator应该适用于IO和列表实例,但是作为一种强类型语言Haskell不允许我这样做。我想我很理解为什么会发生这种事。

问题是:有什么方法可以让我更接近后一种变体吗?或者和前者住在一起还好吗?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-19 05:34:52

您的代码实际上很好,只是您遇到了dreaded monomorphism restriction,这使得Haskell无法推断出replicator最普遍的类型。

本质上,有了限制,Haskell将不会推断不像函数的绑定的多态类型。这意味着它必须为[]IOreplicate选择一个具体的函子,如果您试图在两种不同的上下文中使用它,则会导致一个错误。

您可以通过三种方式使代码工作:

  • 关闭一元形式限制:在模块顶部添加{-# LANGUAGE NoMonomorphismRestriction #-}
  • 使replicator看起来像一个函数: 复制者x= fmap (复制3) x
  • 向代码中添加显式类型签名 复制子::函子f => f a -> f复制子= fmap (复制3)

第三种选择是最惯用的。良好的Haskell风格包括向所有顶级标识符中添加显式类型签名。但是,了解另外两个选项是有用的,它可以理解正在发生的事情,并且能够在Haskell中编写快速和脏的丢弃脚本,而不必担心类型签名。

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32087134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档