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

如何在 GHCi 中定义这个函数的等价物(取自 学会了) ?

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
17618 次浏览

Is there a way provide type declarations in GHCi?

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

Or is there another way to define functions like these which doesn't require type declarations?

If you turn off the monomorphism restriction with -XNoMonomorphismRestriction, it will infer the right type.

Note that you can also avoid the monomorphism restriction simply by adding "points" (i.e. explicit variables) back to your expression. So this also gives the correct type:

let numUniques x = length . nub $ x

The GHC User's Guide shows two additional ways to achieve this. This subsection introduces the :{ ... :} construct, which can be used as follows:

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

Alternatively, you can enable multiline mode:

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