Type inference in haskell and Arrows - haskell

I'm trying to use arrows and faced annoying problem - I have to provide explicit types for all functions I implemented.
If I not provide it ghc outputs some error like
No instance for (Arrow a0) arising from a use of ‘...’
The type variable ‘a0’ is ambiguous
I can provide explicit types but it's VERY annoying, as every time I change some function it's a possibility that I have to manually alter types of every function depended on changed.
Is it possible to force ghc to infer function types automatically?
Trivial case
import Control.Arrow
ss = arr
causes
No instance for (Arrow a0) arising from a use of ‘arr’
The type variable ‘a0’ is ambiguous
Relevant bindings include
ss :: (b -> c) -> a0 b c (bound at src/Main.hs:62:1)
Note: there are several potential instances:
instance Arrow Coroutine -- Defined at src/Main.hs:33:10
instance Arrow (->) -- Defined in ‘Control.Arrow’
instance Monad m => Arrow (Kleisli m) -- Defined in ‘Control.Arrow’
In the expression: arr
In an equation for ‘ss’: ss = arr
while code with exactly the same semantic
import Control.Arrow
ss :: forall a b c. (Arrow a) => (b -> c) -> a b c
ss = arr
compiles pretty well.

Easiest thing is to turn off the monomorphism restriction - put this at the top of your source file:
{-# LANGUAGE NoMonomorphismRestriction #-}
The reason for your error is that although Haskell can infer the type for ss fine, the monomorphism restriction requires that in a top-level definitions of a value, the type is not polymorphic over a type-class (e.g. Arrow) unless there is an explicit type signature.

Related

Why does this function that uses a scoped type variable in a where clause not typecheck?

I have a function that has a value defined in a where clause, and I want to give it an explicit type annotation. The annotation needs to use a type variable from the top-level function, so it was my understanding that I needed to use ScopedTypeVariables. Here is a minimal reduction of the problem:
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad.Trans.Except
import Data.Functor.Identity
f :: ExceptT String Identity a -> Maybe a
f m = Nothing
where x :: Identity (Either String a)
x = runExceptT m
This code does not typecheck. It fails with the following error message:
Couldn't match type ‘a’ with ‘a1’
‘a’ is a rigid type variable bound by
the type signature for f :: ExceptT String Identity a -> Maybe a
at src/Lib.hs:20:6
‘a1’ is a rigid type variable bound by
the type signature for x :: Identity (Either String a1)
at src/Lib.hs:22:14
Expected type: ExceptT String Identity a1
Actual type: ExceptT String Identity a
Relevant bindings include
x :: Identity (Either String a1) (bound at src/Lib.hs:23:9)
m :: ExceptT String Identity a (bound at src/Lib.hs:21:3)
f :: ExceptT String Identity a -> Maybe a
(bound at src/Lib.hs:21:1)
In the first argument of ‘runExceptT’, namely ‘m’
In the expression: runExceptT m
Why does this fail? I do not understand why this would cause problems—it seems like a textbook use of scoped type variables. For reference, I am using GHC 7.10.3.
You need an explicit forall:
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad.Trans.Except
import Data.Functor.Identity
f :: forall a. ExceptT String Identity a -> Maybe a
f m = Nothing
where x :: Identity (Either String a)
x = runExceptT m
but why
That is a great question. This appears to be a rule of ScopedTypeVariables. We know in GHC Haskell that all top-level variables are implicitly forall'd, as documented here. One would suspect that the GHC devs added this behavior for backwards compatibility: without this rule, a file without the extension turned on could stop type-checking once the extension was turned on. We can easily imagine a scenario where helper functions declared in the where block to inadvertently reuse the common type variable names a, b, c, t, so on. It would be great if someone could find the exact spot in the GHC source code where this distinction between explicit and implicit forall'd variables arose.
update
Here we go (although this is all guesswork from the comments and grepping):
While type-checking user signatures, the function tcUserTypeSig invokes findScopedTyVars. TcBinds.hs:ef44606:L1786
findScopedTyVars in TcRnTypes filters for foralls by calling tcSplitForAllTys. TcRnTypes.hs:ef44606:L1221
Which is a wrapper around splitForAllTys, which folds over a type's subtypes to build up a list of type variables introduced by foralls. Types/Type.hs:ef44606:L1361

Multiparameter typeclasses and illegal instance declarations

I made a version of the Convertible class like so:
class Convertible a b where
convert :: a -> b
instance (Convertible a b, Functor f) => Convertible (f a) (f b) where
convert = fmap convert
However, I found it annoying that I would have to make a new instance if I ever wanted to string two conversions together. So I tried adding this:
instance (Convertible a b, Convertible b c) => Convertible a c where
convert = convert . convert
The compiler complained with this:
Variable ‘b’ occurs more often than in the instance head
in the constraint: Convertible a b
(Use UndecidableInstances to permit this)
In the instance declaration for ‘Convertible a c’
Variable ‘b’ occurs more often than in the instance head
in the constraint: Convertible b c
(Use UndecidableInstances to permit this)
In the instance declaration for ‘Convertible a c’
At this point I understand why the compiler is complaining at me, and I'd really rather not turn on UndecidableInstances. The way I currently have my instances set up, there's only one instance of Convertible a b for each a. I hoped that adding a functional dependency a -> b would alleviate this, but now the compiler is complaining about the functor instance:
Illegal instance declaration for ‘Convertible (f a) (f b)’
The coverage condition fails in class ‘Convertible’
for functional dependency: ‘a -> b’
Reason: lhs type ‘f a’ does not determine rhs type ‘f b’
Using UndecidableInstances might help
In the instance declaration for ‘Convertible (f a) (f b)’
Any thoughts about how to get this working? Or perhaps a better design if necessary? I'm thinking I may just have to settle for being explicit about which path of conversions to take.
I think this has to require UndecidableInstances:
instance (Convertible a b, Convertible b c) => Convertible a c where
Given a, thanks to the functional dependency, we can compute a b. However, there's no guarantee that such b is smaller/simpler than a! It could be e.g. that b ~ [[a]], in which case we reduce the problem of checking Convertible a c to checking Convertible [[a]] c. This can easily lead to non-termination during instance search, since the class arguments are not decreasing.
Related note: if you satisfy the functional dependency, there is only one type b to which you can convert a. In such case, why do you need transitivity? There's nothing else a can be converted to. In other words, in the transitivity case you need to have c ~ b, or you would have that a determines both b and c, violating the functional dependency. (I guess you do not really want the functional dependency, after all.)
Unrelated note: also watch out for instance overlaps -- the instance above looks quite troublesome. You might also have to use OverlappingInstances and/or IncoherentInstances, both of which can cause headaches.

Resolving type ambiguities using available class instances

Given the following code:
import Data.Word
data T = T deriving (Eq, Show)
class C a where f :: a -> ()
instance C T where f _ = ()
instance C Word16 where f _ = ()
main = return $ f 0x16
GHC complains that it can't infer what the type for the literal 0x16 should be with the error:
No instance for (Num a0) arising from the literal ‘22’
The type variable ‘a0’ is ambiguous
It is easy to see why this would be -- Haskell allows numeric literals to be of any type which has an instance of Num, and here we can't disambiguate what the type for the literal 0x16 (or 22) should be.
It's also clear as a human reading this what I intended to do -- there is only one available instance of the class C which satisfies the Num constraint, so obviously I intended to use that one so 0x16 should be treated as a Word16.
There are two ways that I know to fix it: Either annotate the literal with its type:
main = return $ f (0x16 :: Word16)
or define a function which essentially does that annotation for you:
w16 x = x :: Word16
main = return $ f (w16 0x16)
I have tried a third way, sticking default (Word16) at the top of the file in the hope that Haskell would pick that as the default type for numeric literals, but I guess I'm misunderstanding what the default keyword is supposed to do because that didn't work.
I understand that typeclasses are open, so just because you can make the assumption in the context quoted above that Word16 is the only numeric instance of C that may not hold in some other module. But my question is: is there some mechanism by which I can assume/enforce that property, so that it is possible to use f and have Haskell resolve the type of its numeric argument to Word16 without explicit annotations at the call site?
The context is that I am implementing an EDSL, and I would rather not have to include manual type hints when I know that my parameters will either be Word16 or some other non-numeric type. I am open to a bit of dirty types/extensions abuse if it makes the EDSL feel more natural! Although if solutions do involve the naughty pragmas I'd definitely appreciate hints on what I should be wary about when using them.
Quick solution with "naughty pragmas" with GHC 7.10:
{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
class C a where f :: a -> ()
instance C T where f _ = ()
instance {-# INCOHERENT #-} (w ~ Word16) => C w where f _ = ()
And with GHC 7.8:
{-# LANGUAGE TypeFamilies, FlexibleInstances, IncoherentInstances #-}
class C a where f :: a -> ()
instance C T where f _ = ()
instance (w ~ Word16) => C w where f _ = ()
Here, GHC essentially picks an arbitrary most specific instance that remains after trying to unify the instances heads and constraints.
You should only use this if
You have a fixed set of instances and don't export the class.
For all use cases of the class method, there is a single possible most specific instance (given the constraints).
Many people advise against ever using IncoherentInstances, but I think it can be quite fun for DSL-s, if we observe the above considerations.
For anybody else wondering about default (I know I was!)
https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3
Quoting section 4.3.4:
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.
So that explains why your default clause is being completely ignored; C is not a standard library type-class.
(As to why this is the rule… can't help you there. Presumably to avoid breaking arbitrary user-defined code.)

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!

List of existentially quantified values in Haskell

I'm wondering why this piece of code doesn't type-check:
{-# LANGUAGE ScopedTypeVariables, Rank2Types, RankNTypes #-}
{-# OPTIONS -fglasgow-exts #-}
module Main where
foo :: [forall a. a]
foo = [1]
ghc complains:
Could not deduce (Num a) from the context ()
arising from the literal `1' at exist5.hs:7:7
Given that:
Prelude> :t 1
1 :: (Num t) => t
Prelude>
it seems that the (Num t) context can't match the () context of arg. The point I can't understand is that since () is more general than (Num t), the latter should and inclusion of the former. Has this anything to do with lack of Haskell support for sub-typing?
Thank you for any comment on this.
You're not using existential quantification here. You're using rank N types.
Here [forall a. a] means that every element must have every possible type (not any, every). So [undefined, undefined] would be a valid list of that type and that's basically it.
To expand on that a bit: if a list has type [forall a. a] that means that all the elements have type forall a. a. That means that any function that takes any kind of argument, can take an element of that list as argument. This is no longer true if you put in an element which has a more specific type than forall a. a, so you can't.
To get a list which can contain any type, you need to define your own list type with existential quantification. Like so:
data MyList = Nil | forall a. Cons a MyList
foo :: MyList
foo = Cons 1 Nil
Of course unless you restrain element types to at least instantiate Show, you can't do anything with a list of that type.
First, your example doesn't even get that far with me for the current GHC, because you need to enable ImpredecativeTypes as well. Doing so results in a warning that ImpredicativeTypes will be simplified or removed in the next GHC. So we're not in good territory here. Nonetheless, adding the proper Num constraint (foo :: [forall a. Num a => a]) does allow your example to compile.
Let's leave aside impredicative types and look at a simpler example:
data Foo = Foo (forall a. a)
foo = Foo 1
This also doesn't compile with the error Could not deduce (Num a) from the context ().
Why? Well, the type promises that you're going to give the Foo constructor something with the quality that for any type a, it produces an a. The only thing that satisfies this is bottom. An integer literal, on the other hand, promises that for any type a that is of class Num it produces an a. So the types are clearly incompatible. We can however pull the forall a bit further out, to get what you probably want:
data Foo = forall a. Foo a
foo = Foo 1
So that compiles. But what can we do with it? Well, let's try to define an extractor function:
unFoo (Foo x) = x
Oops! Quantified type variable 'a' escapes. So we can define that, but we can't do much interesting with it. If we gave a class context, then we could at least use some of the class functions on it.
There is a time and place for existentials, including ones without class context, but its fairly rare, especially when you're getting started. When you do end up using them, often it will be in the context of GADTs, which are a superset of existential types, but in which the way that existentials arise feels quite natural.
Because the declaration [forall a. a] is (in meaning) the equivalent of saying, "I have a list, and if you (i.e. the computer) pick a type, I guarantee that the elements of said list will be that type."
The compiler is "calling your bluff", so-to-speak, by complaining, "I 'know' that if you give me a 1, that its type is in the Num class, but you said that I could pick any type I wanted to for that list."
Basically, you're trying to use the value of a universal type as if it were the type of a universal value. Those aren't the same thing, though.

Resources