使用GHCi时如何为函数提供显式类型声明?


82

我如何在GHCi中定义此函数的等效项(取自learningyouahaskell)?

import Data.List  

numUniques :: (Eq a) => [a] -> Int  
numUniques = length . nub  

如果没有类型声明,GHCi会接受函数定义,但最终会导致无用的类型:

Prelude Data.List> import Data.List 
Prelude Data.List> let numUniques' = length . nub
Prelude Data.List> :t numUniques'
numUniques' :: [()] -> Int

结果函数仅接受单位列表作为参数。

有没有办法在GHCi中提供类型声明?还是有另一种方法来定义这些不需要类型声明的函数?

我在GHCi指南中没有看到明显的线索,并尝试了如下所示的表达式(无济于事):

> let numUniques' = ((length . nub) :: (Eq a) => [a] -> Int)
> :t numUniques'
numUniques' :: [()] -> Int

Answers:


101

有没有办法在GHCi中提供类型声明?

let numUniques' :: (Eq a) => [a] -> Int; numUniques' = length . nub

还是有另一种方法来定义这些不需要类型声明的函数?

如果使用禁用单态限制-XNoMonomorphismRestriction,它将推断出正确的类型。


3
我还不了解单态性,但是通常这个答案将我指向在GHCi中使用分号将定义分组在一起-教程的编写方式类似于.hs文件,在GHCi中尝试时会遇到许多不同的问题(函数缺少绑定等) )。
Tomasz Gandor 2014年

值得一提的是-XNoMonomorphismRestriction:在默认情况下为GHCI因为7.8.1启用downloads.haskell.org/~ghc/latest/docs/html/users_guide/...
N. SHEAD

13

请注意,您还可以通过向表达式中添加“点”(即显式变量)来避免单态性限制。因此,这也给出了正确的类型:

让numUniques x =长度。小结$ x


1
谢谢-很高兴知道。
mattbh 2010年

这就是所谓的ETA-膨胀
Bladt

3

《 GHC用户指南》显示了实现此目的的两种其他方法。本小节介绍了:{...:}构造,该构造可如下使用:

> :{
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| :}

另外,您可以启用多行模式

> :set +m
> let
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.