How to provide explicit type declarations for functions when using GHCi?
HaskellTypesGhciFunction DeclarationHaskell 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
|