首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GHCi忽略类型签名

GHCi忽略类型签名
EN

Stack Overflow用户
提问于 2015-03-22 10:38:02
回答 2查看 663关注 0票数 20
代码语言:javascript
复制
Prelude> let myprint = putStrLn . show
Prelude> :t myprint
myprint :: () -> IO ()

好吧,这里没什么不寻常的。只是GHCi类型的默认规则,我想.

代码语言:javascript
复制
Prelude> let myprint = (putStrLn . show) :: Show x => x -> IO ()
Prelude> :t myprint
myprint :: () -> IO ()

这是什么巫术?你无视我的类型声明?!O_O

有什么办法可以说服GHCi做我真正想做的事吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-22 11:18:16

我们可以通过对以下方面的单形限制来完成以下工作:

代码语言:javascript
复制
>let myprint :: Show x => x -> IO (); myprint = putStrLn . show
>:t myprint
myprint :: Show x => x -> IO ()

这与let myprint = putStrLn . show :: Show x => x -> IO ()不一样。在前一种情况下,我们有一个带有类型签名的绑定,在后一种情况下,我们有一个带有右侧类型注释的let绑定。单体主义检查顶级类型签名,但不检查本地注释。

票数 17
EN

Stack Overflow用户

发布于 2015-03-22 11:24:53

向表达式中添加类型注释,如

代码语言:javascript
复制
e :: type

使编译器检查e是否有该type,并使用该type驱动类型变量实例化和实例选择。但是,如果type是多态的,那么以后仍然可以实例化它。考虑一下。

代码语言:javascript
复制
(id :: a -> a) "hello"

上面,a将被实例化为String,尽管我进行了注释。此外,

代码语言:javascript
复制
foo :: Int -> Int
foo = (id :: a -> a)

将使a在稍后被实例化为Int。上面的id注释没有向GHC提供任何信息:它已经知道id有这种类型。我们可以在不影响类型检查的情况下删除它。也就是说,表达式idid :: a->a不仅是动态等效的,而且在静态上也是等价的。

类似地,表达式

代码语言:javascript
复制
putStrLn . show

代码语言:javascript
复制
(putStrLn . show) :: Show x => x -> IO ()

静态等效:我们只是用GHC可以推断的类型对代码进行注释。换句话说,我们没有向GHC提供任何它还不知道的信息。

在对注释进行类型检查之后,GHC可以进一步实例化x。在你的例子中,单态限制就是这样做的。要防止这种情况,请为您要引入的绑定使用注释,而不是对表达式使用注释。

代码语言:javascript
复制
myprint :: Show x => x -> IO ()
myprint = (putStrLn . show)
票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29193338

复制
相关文章

相似问题

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