How to provide explicit type declarations for functions when using GHCi?

HaskellTypesGhciFunction Declaration

Haskell Problem Overview


How to I define the equivalent of this function (taken from learnyouahaskell) inside GHCi?

import Data.List  

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

Without the type declaration, GHCi accepts the function definition, but it ends up with an unhelpful type:

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

The resulting function only accepts a list of units as a parameter.

Is there a way provide type declarations in GHCi? Or is there another way to define functions like these which doesn't require type declarations?

I saw no obvious clues in the GHCi guide, and experimented with expressions like the following (to no avail):

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

Haskell Solutions


Solution 1 - Haskell

> 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.

Solution 2 - Haskell

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

Solution 3 - Haskell

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
| 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmattbhView Question on Stackoverflow
Solution 1 - Haskellsepp2kView Answer on Stackoverflow
Solution 2 - HaskellsclvView Answer on Stackoverflow
Solution 3 - HaskellReinier TorenbeekView Answer on Stackoverflow