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

Posted

技术标签:

【中文标题】使用 GHCi 时如何为函数提供显式类型声明?【英文标题】:How to provide explicit type declarations for functions when using GHCi? 【发布时间】:2011-03-06 19:23:06 【问题描述】:

如何在 GHCi 中定义这个函数的等效项(取自 learnyouahaskell)?

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

【问题讨论】:

【参考方案1】:

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

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

或者还有其他方法可以定义不需要类型声明的此类函数吗?

如果你用-XNoMonomorphismRestriction关闭单态限制,它会推断出正确的类型。

【讨论】:

我还没有使用单态性,但通常这个答案指向我使用分号将 GHCi 中的定义组合在一起 - 教程就像在 .hs 文件中一样编写,当出现许多不同的问题时在 GHCi 中尝试过(功能缺乏绑定等)。 值得注意的是 -XNoMonomorphismRestriction 从 7.8.1 开始默认为 GHCi 启用:downloads.haskell.org/~ghc/latest/docs/html/users_guide/…【参考方案2】:

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

让 numUniques x = 长度。小块 $x

【讨论】:

谢谢——很高兴知道。 这被称为 eta-expansion【参考方案3】:

GHC 用户指南显示了实现此目的的另外两种方法。 This subsection 引入了: ... : 构造,可以如下使用:

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

或者,您可以启用multiline mode:

> :set +m
> let
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| 

【讨论】:

以上是关于使用 GHCi 时如何为函数提供显式类型声明?的主要内容,如果未能解决你的问题,请参考以下文章

为啥为非泛型方法或构造函数提供显式类型参数会编译?

在 clickhouse 中,使用强制转换函数时如何为可为空的列返回 null

ghci 仅显示类型类方法

go 变量声明总结 --定义 初始化

标C编程笔记day05 函数声明文件读写联合类型枚举类型

如何读取 ghci 类型错误?