Error in ghci which I cannot reproduce in written haskell file - haskell

I tried to check this stackoverflow answer with ghci and get the following error:
> import Data.List
> let m = head . sort
> m [2,3,4]
<interactive>:5:4:
No instance for (Num ()) arising from the literal `2'
Possible fix: add an instance declaration for (Num ())
In the expression: 2
In the first argument of `m', namely `[2, 3, 4]'
In the expression: m [2, 3, 4]
Unfortunately I cannot reproduce the error in a written haskell file:
-- file.hs
import Data.List
main = do
let m = head . sort
putStrLn $ show $ m [2,3,4]
Running this file with runhaskell file.hs gives me the expected value 2. What is my mistake in the ghci session?
Edit: I noted, that the function m has a weird type in ghci:
> import Data.List
> let m = head . sort
> :t m
m :: [()] -> ()
Why is this the case? Shouldn't it has the type Ord a => [a] -> a? For sort and head I get the expected types:
> :t sort
sort :: Ord a => [a] -> [a]
> :t head
head :: [a] -> a

This is the fault of the dreaded Monomorphism restriction. Basically, because you didn't specify a type for m, GHCi guesses it for you. In this case, it guesses that m should have the type [()] -> (), even though that is clearly not what you want. Just give m a type signature in GHCi and you'll be fine.
> :set +m -- multiline expressions, they're handy
> let m :: Ord a => [a] -> a
| m = head . sort
You can disable the Monomorphism restriction with
> :set -XNoMonomorphismRestriction
But it's usually pretty handy, otherwise you have to specify lots of types for things that you normally wouldn't in interactive mode.

Related

Analog for :t from ghci

Reading haskell book about types I want to repeat sample for :t command:
ghci> :t 'a'
'a' :: Char
ghci> :t True
True :: Bool
ghci> :t "HELLO!"
"HELLO!" :: [Char]
ghci> :t (True, 'a')
(True, 'a') :: (Bool, Char)
ghci> :t 4 == 5
4 == 5 :: Bool
Unfortunately I can't install haskell locally, thatswhy I use ideone.com
But I can't understand how create the same sample.
I tried like this:
main = do
putStrLn "Start"
:t 'a'
putStrLn "Finish"
or this:
:t 'a'
or:
putStrLn ("Finish" ++ show :t 'a')
Is there a possibility to show types without installing ghci? Maybe, there is another web fiddle that can do this?
You can use typeOf :: forall a. Typeable a => a -> TypeRep to obtain the TypeRep object. It requires that your type is Typeable, but with the given examples that is the case.
For example:
import Data.Typeable(typeOf)
main = putStrLn ("Finish" ++ show (typeOf 'a'))
This will not print full polymorphic types, since at compile time the types are determined. You thus see the type as is derived by the Haskell compiler.

Ambiguous type variable but not in ghci?

Can anybody explain why haskell enforces explicit type signature in the following example and how to modify it to avoid need of the explicit declaration ?
import qualified Data.List as L
main = do
print $ length $ L.nub [1,1,2,3] -- 3, passed (Eq a, Num a) => [a]
print $ length $ L.nub [] -- ambiguous type error, passed (Eq a) => [a]
-- can help type system with explicit signature but how to avoid ?
print $ length $ L.nub ([] :: [Int])
Surprisingly the same code written interactively in ghci has no issue with ambiguity and does prints zero length:
λ> :m +Data.List
λ> print $ length $ nub []
0 -- ?? can you explain ??
Update:
It seems even same restricted as Data.List.nub length function won't stop complaints about ambiguous type:
length' :: Eq a => [a] -> Int
length' [] = 0
length' (x:xs) = 1 + length' xs
main = do
print $ length' $ nub []
-- No instance for (Eq a0) arising from a use of ‘length'’
-- The type variable ‘a0’ is ambiguous
The problem is that [] has the polymorphic type (Eq a) => [a]. Since length doesn't add any particular constraint.
Specifically the type of length is:
length :: [a] -> Int
which is even more permissive than nub:
nub :: Eq a => [a] -> [a]
The compiler needs to use a specific instance of length there and is not able to deduce a type for a.
Now you have two options:
Turn on the ExtendedDefaultRules extension with {-# LANGUAGE ExtendedDefaultRules #-} at the beginning of the file.
Be explicit: ... L.nub ([] :: [Int])
I'd recommend the 2nd one by default, unless you fully understand the consequences of the first one.

What make the difference between `:t` and let expression in GHCi

I want to make a toy function that produces a Maybe a and then lift show to make it a Maybe String, but the outcome was weird for me:
λ> :t liftM show . Just
liftM show . Just :: Show a1 => a1 -> Maybe String
λ> liftM show . Just $ 10
Just "10"
λ> let f = liftM show . Just
λ> f 10
<interactive>:9:3:
No instance for (Num ()) arising from the literal `10'
Possible fix: add an instance declaration for (Num ())
In the first argument of `f', namely `10'
In the expression: f 10
In an equation for `it': it = f 10
λ> :t f
f :: () -> Maybe String
λ> let g = liftM show . Just :: (Show a) => a -> Maybe String
λ> :t g
g :: () -> Maybe String
λ> let h = liftM show . Just :: Int -> Maybe String
λ> :t h
h :: Int -> Maybe String
I guess it has something to do with type inference, but I really don't know what happened:
where did that mysterious () come from?
why GHCi didn't complain about ambiguousness?
Dum-duuum!
Next victim of the dreaded monomorphism restriction.
What happens is this: for a definition that looks like a "constant variable" (in the sense that other languages might also use, i.e. not of function type), like f = ..., it is assumed that you wish it to actually behave like a constant (CAF, to be precise). That means, it must not be polymorphic, since with parametric polymorphism there's basically an extra implicit argument to the function (the information which type a1 should be).
To achieve this actual-const-ness, ghci defaults this type variable to whatever specific type it deems least inappropriate. Here, the only constraint is Show; the simplest type fulfilling that is ().
The "correct" way of getting around this is to turn off the monomorphism restriction:
Prelude> :set -XNoMonomorphismRestriction
Prelude> :m +Control.Monad
Prelude Control.Monad> let f = liftM show . Just
Prelude Control.Monad> f 10
Just "10"
Alternatively, you can, like in an actual source file you always should, give proper signatures to identifiers in ghci:
Prelude Control.Monad> let g :: Show a => a -> Maybe String; g = liftM show . Just
Prelude Control.Monad> g 10
Just "10"
Doing that only on the RHS of the = doesn't work, since the monomorphism restriction kicks in only after that is resolved and defaults away the variables (unless, as in h, there are no variables in the first place because you gave a monomorphic signature to the RHS).
Still another thing you can do, simply give the function an explicit argument, then the monomorphism restriction doesn't apply at all. I.e., write it non–point-free:
Prelude Control.Monad> let i a = liftM show $ Just a
Prelude Control.Monad> i 10
Just "10"

Why is GHCi typing this statement oddly?

In answering a question on stackoverflow, I noticed that GHCi (interactive) is assigning a too-restrictive type in a let statement. Namely, given the code,
import Control.Arrow
f = maximum &&& id >>> fst &&& (\(m,l) -> length $ filter (==m) l)
(as on my answer to https://stackoverflow.com/questions/6281813/maximum-of-list-and-count-of-repeat-maximum-number/6283594#6283594), if one inserts a "let" before f and enters this in ghci, it gives the following type information
Prelude Control.Arrow> :t f
f :: [()] -> ((), Int)
whereas just asking for the type of the expression gives the correct result, namely Ord a => [a] -> (a, Int). I'm using ghc 7.0.3.
See the extended defaulting rules used in GHCi for an explanation of where the () is coming from.
As for why the defaulting occurs in this case, compare the following:
> let f x = maximum &&& id >>> fst &&& (\(m,l) -> length $ filter (==m) l) $ x
> :t f
f :: (Ord a) => [a] -> (a, Int)
I assume this has something to do with bindings being monomorphic, but I'm not certain of the details.

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

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

Resources