Haskell: Loading a file with a definition fails, while doing it interactively in GHCi works well. Why? - haskell

I am using GHCi 8.10.2 on Win 10.
I have a source file named src\LoadAndInteractiveDiffer.hs containing only:
module LoadAndInteractiveDiffer where
testNothingIsNothing = Nothing == Nothing
When loading it into GHCi, I get:
Prelude> :l src/LoadAndInteractiveDiffer.hs
[1 of 1] Compiling LoadAndInteractiveDiffer ( src\LoadAndInteractiveDiffer.hs, interpreted )
src\LoadAndInteractiveDiffer.hs:3:24: error:
* Ambiguous type variable `a0' arising from a use of `=='
prevents the constraint `(Eq a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
These potential instances exist:
instance Eq Ordering -- Defined in `GHC.Classes'
instance Eq Integer
-- Defined in `integer-gmp-1.0.3.0:GHC.Integer.Type'
instance Eq a => Eq (Maybe a) -- Defined in `GHC.Maybe'
...plus 22 others
...plus six instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In the expression: Nothing == Nothing
In an equation for `testNothingIsNothing':
testNothingIsNothing = Nothing == Nothing
|
3 | testNothingIsNothing = Nothing == Nothing
| ^^^^^^^^^^^^^^^^^^
Failed, no modules loaded.
However, when I do the same thing interactively, the behavior is as expected:
-- Works fine:
Prelude> testNothingIsNothing = Nothing == Nothing
Prelude>
-- Works fine:
Prelude> testNothingIsNothing
True
What have I missed here?

You need to specify the type a of Maybe a. In ghci it makes a guess and will do type defaulting.
Here we can for example work with Integer, since Integer is a member of the Eq typeclass:
testNothingIsNothing = Nothing == (Nothing :: Maybe Integer)
GHCi has extended defaulting rules [haskell-report]. Since here there is only a type constraint Eq on a, it will normally work with Maybe (). For more information about type defaulting, you can reed this article named "Type defaulting in Haskell" of Kwang's Haskell blog.
You can enable the extended type defaulting for a file with a language pragma:
{-# LANGUAGE ExtendedDefaultRules #-}
testNothingIsNothing = Nothing == Nothing
In fact you can enable it for some files, and for others, you do not. For the interactive part of ghci, this is enabled.

Nothing has type Maybe a. a must be filled in to use the type, but there is nothing in your program to let GHc infer what the a might be, hence the error.
When GHCi encounters an ambiguous type variable at the prompt, it uses Defaulting rules to resolve them, So Nothing is defaulted to Maybe (). However, when it loads a module from a file, the normal GHC convention is followed (unless the extension ExtendedDefaultRules is enabled, in which case GHCi-style defaulting is always enabled).

Related

Why such different behaviour with `Ambiguous type..` error (in ghci)?

This example works with ghci, load this file:
import Safe
t1 = tailMay []
and put in ghci:
> print t1
Nothing
But if we add analogous definition to previous file, it doesn't work:
import Safe
t1 = tailMay []
t2 = print $ tailMay []
with such error:
* Ambiguous type variable `a0' arising from a use of `print'
prevents the constraint `(Show a0)' from being solved.
Probable fix: use a type annotation to specify what `a0' should be.
These potential instances exist:
instance Show Ordering -- Defined in `GHC.Show'
instance Show Integer -- Defined in `GHC.Show'
instance Show a => Show (Maybe a) -- Defined in `GHC.Show'
...plus 22 others
That is 3rd sample for ghc with the same error:
import Safe
t1 = tailMay
main = do
print $ t1 []
print $ t1 [1,2,3]
Why? And how to fix the second sample without explicit type annotation?
The issue here is that tailMay [] can generate an output of type Maybe [a] for any a, while print can take an input of type Maybe [a] for any a (in class Show).
When you compose a "universal producer" and a "universal consumer", the compiler has no idea about which type a to pick -- that could be any type in class Show. The choice of a could matter since, in principle, print (Nothing :: Maybe [Int]) could print something different from print (Nothing :: Maybe [Bool]). In this case, the printed output would be the same, but only because we are lucky.
For instance print ([] :: [Int]) and print ([] :: [Char]) will print different messages, so print [] is ambiguous. Hence, GHC reject it, and requires an explicit type annotation (or a type application # type, using an extension).
Why, then, such ambiguity is accepted in GHCi? Well, GHCi is meant to be used for quick experiments, and as such, as a convenience feature, it will try hard to default these ambiguous a. This is done using the extended defaulting rules, which could (I guess) in principle be turned on in GHC as well by turning on that extension.
This is, however, not recommended since sometimes the defaulting rule can choose some unintended type, making the code compile but with an unwanted runtime behavior.
The common solution to this issue is using an annotation (or # type), because it provides more control to the programmer, makes the code easier to read, and avoids surprises.

Problem when defining Int as an instance of a type class in Haskell

I am trying to define Int as an instance of my type class Add.
I wanted to define my own operator +++, which should be overloaded on integers and strings. My goal was to be able to add integers and concatenate strings with the same operator. Therefore i created the type class Add with the instances Int and [char]:
class Add a where
(+++) :: a -> a -> a
instance Add Int where
x +++ y = x + y
instance Add [char] where
x +++ y = x ++ y
Problem: When evaluating the expression 1 +++ 2, GHCi gives me the following error message:
<interactive>:9:1: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘print’
prevents the constraint ‘(Show a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
...plus 22 others
...plus 18 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In a stmt of an interactive GHCi command: print it
But when defining Integer as an instance of Add
instance Add Integer where
x +++ y = x + y
GHCi can evaluate 1 +++ 2 to 3 and i don't get an error.
Question: Why is it not working, when using Int as an instance? What is the difference in using Int or Integer?
Given that it works for Integer but not Int, I'm fairly sure this is due to "type defaulting".
In GHCi (and to a lesser extent in compiled code), if an expression has an ambiguous type, the compiler tries several "default types", which of which is Integer (but not Int). That's almost certainly where the difference is coming from.
I suspect if you add :: Int to the end of your expression, it will execute just fine. The problem isn't that there's a type error, it's that more than one type potentially fits, and the compiler isn't sure which one you intended.
I've never tried this, but I believe you can change the defaults by saying something like default (Int, Double). (Usually it's default (Integer, Double).) I think that's the right syntax; not 100% sure.
There's a bit about this in the GHCi manual: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html#type-defaulting-in-ghci
Also the Haskell Report: https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3 (Section 4.3.4)

Haskell function composition confusion

I'm trying to learn haskell and I've been going over chapter 6 and 7 of Learn you a Haskell. Why don't the following two function definitions give the same result? I thought (f . g) x = f (g (x))?
Def 1
let{ t :: Eq x => [x] -> Int; t xs = length( nub xs)}
t [1]
1
Def 2
let t = length . nub
t [1]
<interactive>:78:4:
No instance for (Num ()) arising from the literal `1'
Possible fix: add an instance declaration for (Num ())
In the expression: 1
In the first argument of `t', namely `[1]'
In the expression: t [1]
The problem is with your type signatures and the dreaded monomorphism restriction. You have a type signature in your first version but not in your second; ironically, it would have worked the other way around!
Try this:
λ>let t :: Eq x => [x] -> Int; t = length . nub
λ>t [1]
1
The monomorphism restriction forces things that don't look like functions to have a monomorphic type unless they have an explicit type signature. The type you want for t is polymorphic: note the type variable x. However, with the monomorphism restriction, x gets "defaulted" to (). Check this out:
λ>let t = length . nub
λ>:t t
t :: [()] -> Int
This is very different from the version with the type signature above!
The compiler chooses () for the monomorphic type because of defaulting. Defaulting is just the process Haskell uses to choose a type from a typeclass. All this really means is that, in the repl, Haskell will try using the () type if it encounters an ambiguous type variable in the Show, Eq or Ord classes. Yes, this is basically arbitrary, but it's pretty handy for playing around without having to write type signatures everywhere! Also, the defaulting rules are more conservative in files, so this is basically just something that happens in GHCi.
In fact, defaulting to () seems to mostly be a hack to make printf work correctly in GHCi! It's an obscure Haskell curio, but I'd ignore it in practice.
Apart from including a type signature, you could also just turn the monomorphism restriction off in the repl:
λ>:set -XNoMonomorphismRestriction
This is fine in GHCi, but I would not use it in real modules--instead, make sure to always include a type signature for top-level definitions inside files.
EDIT: Ever since GHC 7.8.1, the monomorphism restriction is turned off by default in GHCi. This means that all this code would work fine with a recent version of GHCi and you do not need to set the flag explicitly. It can still be an issue for values defined in a file with no type signature, however.
This is another instance of the "Dreaded" Monomorphism Restriction which leads GHCi to infer a monomorphic type for the composed function. You can disable it in GHCi with
> :set -XNoMonomorphismRestriction

Ambiguous type variable with HashMap

I recently starting to play with haskell and I came across a problem while using HashMap that can be illustrated by this toy example:
import Data.HashMap as HashMap
foo = HashMap.insert 42 53 HashMap.empty
Here is the error I get when I load my file in the interpreter or compile it:
Prelude List HashMap> :load TypeError.hs
[1 of 1] Compiling Main ( TypeError.hs, interpreted )
TypeError.hs:3:22:
Ambiguous type variable `k0' in the constraints:
(Num k0) arising from the literal `42' at TypeError.hs:3:22-23
(Ord k0) arising from a use of `insert' at TypeError.hs:3:7-20
(Data.Hashable.Hashable k0)
arising from a use of `insert' at TypeError.hs:3:7-20
Possible cause: the monomorphism restriction applied to the following:
foo :: Map k0 Integer (bound at TypeError.hs:3:1)
Probable fix: give these definition(s) an explicit type signature
or use -XNoMonomorphismRestriction
In the first argument of `insert', namely `42'
In the expression: insert 42 53 empty
In an equation for `foo': foo = insert 42 53 empty
Failed, modules loaded: none.
Prelude List HashMap>
However if I define the exact same function directly in the interpreter, I get no error:
Prelude List HashMap> let foo = HashMap.insert 42 53 HashMap.empty
Prelude List HashMap>
Does anyone have any clue about this?
Thanks.
The reason is that ghci uses extended default rules, while the compiler uses (by default) the defaulting rules specified in the language report:
Ambiguities in the class Num are most common, so Haskell provides another way to resolve them—with a default declaration: default (t1 , … , tn) where n ≥ 0, and each ti must be a type for which Num ti holds. In situations where an ambiguous type is discovered, an ambiguous type variable, v, is defaultable if:
v appears only in constraints of the form C v, where C is a class, and
at least one of these classes is a numeric class, (that is, Num or a subclass of Num), and
all of these classes are defined in the Prelude or a standard library
The relevant rule is that per the report defaulting is only done if all involved classes are defined in a standard library, but the Hashable constraint on the key involves a class that doesn't meet that requirement.
Thus the compiler rejects it, because it can't resolve the ambiguous type variable arising from the key, while ghci defaults it to Integer, since ghci also defaults if other classes are involved.

haskell -- odd ambiguous type variable error message for code in "where" statement with TypeFamilies extension

Does anyone know why this code fails?
{-# LANGUAGE NoMonomorphismRestriction,
TypeFamilies #-}
module Test where
asExprTyp :: Expr γ =>
γ α
-> α
-> γ α
asExprTyp x _ = x
int = undefined :: Integer
class Expr γ where
a :: γ α
-- this works fine
b = a `asExprTyp` int
-- this fails
mcode = do
return ()
where b = a `asExprTyp` int
The error is as follows,
Test.hs:23:15:
Ambiguous type variable `γ0' in the constraint:
(Expr γ0) arising from a use of `a'
Probable fix: add a type signature that fixes these type variable(s)
In the first argument of `asExprTyp', namely `a'
In the expression: a `asExprTyp` int
In an equation for `b': b = a `asExprTyp` int
Failed, modules loaded: none.
I don't see what ghc complains about either. I thought it might be because it's trying to give the local binding a monomorphic type, but adding NoMonoLocalBinds to the language pragma didn't change anything.
However, the code compiles as is with a recent HEAD (7.3.20111026), together with the fact that it compiles without TypeFamilies enabled, that supports the bug hypothesis.
If it's a real problem you have to solve: adding type signatures makes ghc happy.
Okay, this is somewhat over my head since I've never used type families in Haskell. However, your example isn't actually using type families either, so I thought I'd see what happens when I remove the TypeFamilies language extension from the LANGUAGE pragma. Turns out: it compiles just fine then! :)
So it could very well be a GHC bug.
That being said, I poked at it a bit and noticed that the following compiles happily with TypeFamilies enabled:
mcode = do
b
return ()
where b = a `asExprTyp` int
This is probably nonsensical, since its inferred type is mcode :: (Expr m, Monad m) => m (), rather than just mcode :: Monad m => m (), but my point is that GHC seems happy only when a's type is tied in some way to mcode's type.
Not sure if this is helpful, but it definitely piqued my curiosity!

Resources