Incomplete implicit type inference in Haskell - haskell

Let's consider the following example:
data A = A{x::Int} deriving(Show)
instance Func_f (A -> String) where
f _ = "ala"
class Func_f a where
f :: a
main :: IO ()
main = do
let
a = A 5
x = f a
print 5
compiled with ghc -XFlexibleInstances main.hs
(I've tried -XExtendedDefaultRules, but without any progress)
Why while compiling we get an error?:
main.hs:25:21:
No instance for (Func_f (A -> t0)) arising from a use of `f'
The type variable `t0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there is a potential instance available:
instance Func_f (A -> String) -- Defined at main.hs:7:10
Possible fix: add an instance declaration for (Func_f (A -> t0))
In the expression: f a
In an equation for `x': x = f a
In the expression:
do { let a = A 5
x = f a;
print 5 }
There is only one instance for Func_f, so Haskell should be able to know the result of x = f a. You can fix the error by providing the type manually, like this: x = f a :: String, but this is not suitable for my case, because I'm generating Haskell code and I would love the Haskell's type inferencer to do this job for me.

You're running into the open world assumption. The basic idea is that GHC always assumes that you could add more class instances to your code. Moreover, you cannot control how instances get exported and imported between modules. So relying on only having one instance of a particular class is not going to work and would lead to weird bugs.
Essentially, nothing stops you--or anybody else, for that matter--from writing another instance like:
instance Func_f (A -> Int) where
f _ = 10
and it would then be impossible to figure out which one you wanted in your code. This could cause your code to break just from linking against another module!
However, if you actually used the value, chances are it would get its type constrained by some other parameter and the ambiguity would go away. For example, the following works:
main :: IO ()
main = do
let a = A 5
x = f a
putStr x
Basically, this is one of those cases (similar to read . show) where a type signature is simply unavoidable because of how GHC treats typeclass instances.

There is only one instance for Func_f, so Haskell should be able to know the result of x = f a
This violates the open world assumption.

Related

It is possible to define a function in haskell that takes one parameter, ignores it, and returns itself?

I would like to define the following function:
f a = f
This function takes one argument and returns itself ignoring the argument. Just writing it like this in ghci gives me the following type error:
• Couldn't match expected type ‘t’ with actual type ‘p0 -> t’
‘t’ is a rigid type variable bound by
the inferred type of f :: t
If the function would use this argument it would be possible (as in this halt example):
halt = halt
or with one parameter
halt x = halt x
Would it somehow be possible to name this type or compile the former program? Of course, this is not for any specific reason, just trying to understand type theory, specifically in haskell, better - you could never apply this function enough to yield a specific result.
Well, you can "almost" have that.
As already mentioned, you can't have an infinite type like a -> b -> c -> ..., since Haskell types must be finite.
However, we can define a recursive newtype which is "morally" the infinite type above, and use that:
newtype F = F { unF :: forall a. a -> F }
f :: F
f = F (\x -> f)
In simpler terms, this constructs a type F satisfying F ~= forall a . a -> F which is the equation giving rise to the wanted "infinite" type.
Note the use of the forall a to allow x to have any type at all. The (almost-)function f is essentially a "hungry" function that will eat any argument, of any type, and return itself.
There is a downside, though, to this approach. To actually apply f, we need to unwrap the constructor. This leads to code like
g :: F
g = unF (unF f True) "hello"
which is a bit more inconvenient than g = f True "hello".

How do you apply function constraints in instance methods in Haskell?

I'm learning how to use typeclasses in Haskell.
Consider the following implementation of a typeclass T with a type constrained class function f.
class T t where
f :: (Eq u) => t -> u
data T_Impl = T_Impl_Bool Bool | T_Impl_Int Int | T_Impl_Float Float
instance T T_Impl where
f (T_Impl_Bool x) = x
f (T_Impl_Int x) = x
f (T_Impl_Float x) = x
When I load this into GHCI 7.10.2, I get the following error:
Couldn't match expected type ‘u’ with actual type ‘Float’
‘u’ is a rigid type variable bound by
the type signature for f :: Eq u => T_Impl -> u
at generics.hs:6:5
Relevant bindings include
f :: T_Impl -> u (bound at generics.hs:6:5)
In the expression: x
In an equation for ‘f’: f (T_Impl_Float x) = x
What am I doing/understanding wrong? It seems reasonable to me that one would want to specialize a typeclass in an instance by providing an accompaning data constructor and function implementation. The part
Couldn't match expected type 'u' with actual type 'Float'
is especially confusing. Why does u not match Float if u only has the constraint that it must qualify as an Eq type (Floats do that afaik)?
The signature
f :: (Eq u) => t -> u
means that the caller can pick t and u as wanted, with the only burden of ensuring that u is of class Eq (and t of class T -- in class methods there's an implicit T t constraint).
It does not mean that the implementation can choose any u.
So, the caller can use f in any of these ways: (with t in class T)
f :: t -> Bool
f :: t -> Char
f :: t -> Int
...
The compiler is complaining that your implementation is not general enough to cover all these cases.
Couldn't match expected type ‘u’ with actual type ‘Float’
means "You gave me a Float, but you must provide a value of the general type u (where u will be chosen by the caller)"
Chi has already pointed out why your code doesn't compile. But it's not even that typeclasses are the problem; indeed, your example has only one instance, so it might just as well be a normal function rather than a class.
Fundamentally, the problem is that you're trying to do something like
foobar :: Show x => Either Int Bool -> x
foobar (Left x) = x
foobar (Right x) = x
This won't work. It tries to make foobar return a different type depending on the value you feed it at run-time. But in Haskell, all types must be 100% determined at compile-time. So this cannot work.
There are several things you can do, however.
First of all, you can do this:
foo :: Either Int Bool -> String
foo (Left x) = show x
foo (Right x) = show x
In other words, rather than return something showable, actually show it. That means the result type is always String. It means that which version of show gets called will vary at run-time, but that's fine. Code paths can vary at run-time, it's types which cannot.
Another thing you can do is this:
toInt :: Either Int Bool -> Maybe Int
toInt (Left x) = Just x
toInt (Right x) = Nothing
toBool :: Either Int Bool -> Maybe Bool
toBool (Left x) = Nothing
toBool (Right x) = Just x
Again, that works perfectly fine.
There are other things you can do; without knowing why you want this, it's difficult to suggest others.
As a side note, you want to stop thinking about this like it's object oriented programming. It isn't. It requires a new way of thinking. In particular, don't reach for a typeclass unless you really need one. (I realise this particular example may just be a learning exercise to learn about typeclasses of course...)
It's possible to do this:
class Eq u => T t u | t -> u where
f :: t -> u
You need FlexibleContextx+FunctionalDepencencies and MultiParamTypeClasses+FlexibleInstances on call-site. Or to eliminate class and to use data types instead like Gabriel shows here

What if function application was a typeclass?

Suppose Haskell's function application (the "space" operator) were in a typeclass instead of baked into the language. I imagine it would look something like
class Apply f where
($) :: f a r -> a -> r
instance Apply (->) where
($) = builtinFnApply#
And f a would desugar to f $ a. The idea is that this would let you define other types that act like functions, ie
instance Apply LinearMap where
($) = matrixVectorMult
and so on.
Does this make type inference undecidable? My instinct says that it does, but my understanding of type inference stops at plain Hindley-Milner. As a follow up, if it is undecidable, can it be made decidable by outlawing certain pathological instances?
If you can envision this as a syntactic sugar on top of Haskell (replacing the "space operator" with yours), I can't see why this should make type inference any worse than it already is.
I can however see that code might be more ambiguous with this change, e.g.
class C a where get :: a
instance C (Int -> Int) where get = id
instance C Linearmap where get = ...
test = get (5 :: Int) -- actually being (get $ (5 :: Int))
Above get could be picked from both instances, while such ambiguity does not arise in plain Haskell.

How do I resolve this compile error: Ambiguous type variable `a1' in the constraint

One could think of this case as follows:
The application dynamically loads a module, or there is a list of functions from which the user chooses, etc. We have a mechanism for determining whether a certain type will successfully work with a function in that module. So now we want to call into that function. We need to force it to make the call. The function could take a concrete type, or a polymorphic one and it's the case below with just a type class constraint that I'm running into problems with it.
The following code results in the errors below. I think it could be resolved by specifying concrete types but I do not want to do that. The code is intended to work with any type that is an instance of the class. Specifying a concrete type defeats the purpose.
This is simulating one part of a program that does not know about the other and does not know the types of what it's dealing with. I have a separate mechanism that allows me to be sure that the types do match up properly, that the value sent in really is an instance of the type class. That's why in this case, I don't mind using unsafeCoerce. But basically I need a way to tell the compiler that I really do know it's ok and do it anyway even though it doesn't know enough to type check.
{-# LANGUAGE ExistentialQuantification, RankNTypes, TypeSynonymInstances #-}
module Main where
import Unsafe.Coerce
main = do
--doTest1 $ Hider "blue"
doTest2 $ Hider "blue"
doTest1 :: Hider -> IO ()
doTest1 hh#(Hider h) =
test $ unsafeCoerce h
doTest2 :: Hider -> IO ()
doTest2 hh#(Hider h) =
test2 hh
test :: HasString a => a -> IO ()
test x = print $ toString x
test2 :: Hider -> IO ()
test2 (Hider x) = print $ toString (unsafeCoerce x)
data Hider = forall a. Hider a
class HasString a where
toString :: a -> String
instance HasString String where
toString = id
Running doTest1
[1 of 1] Compiling Main ( Test.hs, Test.o )
Test.hs:12:3:
Ambiguous type variable `a1' in the constraint:
(HasString a1) arising from a use of `test'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: test
In the expression: test $ unsafeCoerce h
In an equation for `doTest1':
doTest1 hh#(Hider h) = test $ unsafeCoerce h
Running doTest2
[1 of 1] Compiling Main ( Test.hs, Test.o )
Test.hs:12:3:
Ambiguous type variable `a1' in the constraint:
(HasString a1) arising from a use of `test'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: test
In the expression: test $ unsafeCoerce h
In an equation for `doTest1':
doTest1 hh#(Hider h) = test $ unsafeCoerce h
I think it could be resolved by specifying concrete types but I do not want to do that.
There's no way around it though with unsafeCoerce. In this particular case, the compiler can't infer the type of unsafeCoerce, because test is still to polymorphic. Even though there is just one instance of HasString, the type system won't use that fact to infer the type.
I don't have enough information about your particular application of this pattern, but I'm relatively sure that you need to rethink the way you use the type system in your program. But if you really want to do this, you might want to look into Data.Typeable instead of unsafeCoerce.
Modify your data type slightly:
data Hider = forall a. HasString a => Hider a
Make it an instance of the type class in the obvious way:
instance HasString Hider where
toString (Hider x) = toString x
Then this should work, without use of unsafeCoerce:
doTest3 :: Hider -> IO ()
doTest3 hh = print $ toString hh
This does mean that you can no longer place a value into a Hider if it doesn't implement HasString, but that's probably a good thing.
There's probably a name for this pattern, but I can't think what it is off the top of my head.

Haskell get type of algebraic parameter

I have a type
class IntegerAsType a where
value :: a -> Integer
data T5
instance IntegerAsType T5 where value _ = 5
newtype (IntegerAsType q) => Zq q = Zq Integer deriving (Eq)
newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]
I'm trying to make a nice "show" for the PolyRing type. In particular, I want the "show" to print out the type 'a'. Is there a function that returns the type of an algebraic parameter (a 'show' for types)?
The other way I'm trying to do it is using pattern matching, but I'm running into problems with built-in types and the algebraic type.
I want a different result for each of Integer, Int and Zq q.
(toy example:)
test :: (Num a, IntegerAsType q) => a -> a
(Int x) = x+1
(Integer x) = x+2
(Zq x) = x+3
There are at least two different problems here.
1) Int and Integer are not data constructors for the 'Int' and 'Integer' types. Are there data constructors for these types/how do I pattern match with them?
2) Although not shown in my code, Zq IS an instance of Num. The problem I'm getting is:
Ambiguous constraint `IntegerAsType q'
At least one of the forall'd type variables mentioned by the constraint
must be reachable from the type after the '=>'
In the type signature for `test':
test :: (Num a, IntegerAsType q) => a -> a
I kind of see why it is complaining, but I don't know how to get around that.
Thanks
EDIT:
A better example of what I'm trying to do with the test function:
test :: (Num a) => a -> a
test (Integer x) = x+2
test (Int x) = x+1
test (Zq x) = x
Even if we ignore the fact that I can't construct Integers and Ints this way (still want to know how!) this 'test' doesn't compile because:
Could not deduce (a ~ Zq t0) from the context (Num a)
My next try at this function was with the type signature:
test :: (Num a, IntegerAsType q) => a -> a
which leads to the new error
Ambiguous constraint `IntegerAsType q'
At least one of the forall'd type variables mentioned by the constraint
must be reachable from the type after the '=>'
I hope that makes my question a little clearer....
I'm not sure what you're driving at with that test function, but you can do something like this if you like:
{-# LANGUAGE ScopedTypeVariables #-}
class NamedType a where
name :: a -> String
instance NamedType Int where
name _ = "Int"
instance NamedType Integer where
name _ = "Integer"
instance NamedType q => NamedType (Zq q) where
name _ = "Zq (" ++ name (undefined :: q) ++ ")"
I would not be doing my Stack Overflow duty if I did not follow up this answer with a warning: what you are asking for is very, very strange. You are probably doing something in a very unidiomatic way, and will be fighting the language the whole way. I strongly recommend that your next question be a much broader design question, so that we can help guide you to a more idiomatic solution.
Edit
There is another half to your question, namely, how to write a test function that "pattern matches" on the input to check whether it's an Int, an Integer, a Zq type, etc. You provide this suggestive code snippet:
test :: (Num a) => a -> a
test (Integer x) = x+2
test (Int x) = x+1
test (Zq x) = x
There are a couple of things to clear up here.
Haskell has three levels of objects: the value level, the type level, and the kind level. Some examples of things at the value level include "Hello, world!", 42, the function \a -> a, or fix (\xs -> 0:1:zipWith (+) xs (tail xs)). Some examples of things at the type level include Bool, Int, Maybe, Maybe Int, and Monad m => m (). Some examples of things at the kind level include * and (* -> *) -> *.
The levels are in order; value level objects are classified by type level objects, and type level objects are classified by kind level objects. We write the classification relationship using ::, so for example, 32 :: Int or "Hello, world!" :: [Char]. (The kind level isn't too interesting for this discussion, but * classifies types, and arrow kinds classify type constructors. For example, Int :: * and [Int] :: *, but [] :: * -> *.)
Now, one of the most basic properties of Haskell is that each level is completely isolated. You will never see a string like "Hello, world!" in a type; similarly, value-level objects don't pass around or operate on types. Moreover, there are separate namespaces for values and types. Take the example of Maybe:
data Maybe a = Nothing | Just a
This declaration creates a new name Maybe :: * -> * at the type level, and two new names Nothing :: Maybe a and Just :: a -> Maybe a at the value level. One common pattern is to use the same name for a type constructor and for its value constructor, if there's only one; for example, you might see
newtype Wrapped a = Wrapped a
which declares a new name Wrapped :: * -> * at the type level, and simultaneously declares a distinct name Wrapped :: a -> Wrapped a at the value level. Some particularly common (and confusing examples) include (), which is both a value-level object (of type ()) and a type-level object (of kind *), and [], which is both a value-level object (of type [a]) and a type-level object (of kind * -> *). Note that the fact that the value-level and type-level objects happen to be spelled the same in your source is just a coincidence! If you wanted to confuse your readers, you could perfectly well write
newtype Huey a = Louie a
newtype Louie a = Dewey a
newtype Dewey a = Huey a
where none of these three declarations are related to each other at all!
Now, we can finally tackle what goes wrong with test above: Integer and Int are not value constructors, so they can't be used in patterns. Remember -- the value level and type level are isolated, so you can't put type names in value definitions! By now, you might wish you had written test' instead:
test' :: Num a => a -> a
test' (x :: Integer) = x + 2
test' (x :: Int) = x + 1
test' (Zq x :: Zq a) = x
...but alas, it doesn't quite work like that. Value-level things aren't allowed to depend on type-level things. What you can do is to write separate functions at each of the Int, Integer, and Zq a types:
testInteger :: Integer -> Integer
testInteger x = x + 2
testInt :: Int -> Int
testInt x = x + 1
testZq :: Num a => Zq a -> Zq a
testZq (Zq x) = Zq x
Then we can call the appropriate one of these functions when we want to do a test. Since we're in a statically-typed language, exactly one of these functions is going to be applicable to any particular variable.
Now, it's a bit onerous to remember to call the right function, so Haskell offers a slight convenience: you can let the compiler choose one of these functions for you at compile time. This mechanism is the big idea behind classes. It looks like this:
class Testable a where test :: a -> a
instance Testable Integer where test = testInteger
instance Testable Int where test = testInt
instance Num a => Testable (Zq a) where test = testZq
Now, it looks like there's a single function called test which can handle any of Int, Integer, or numeric Zq's -- but in fact there are three functions, and the compiler is transparently choosing one for you. And that's an important insight. The type of test:
test :: Testable a => a -> a
...looks at first blush like it is a function that takes a value that could be any Testable type. But in fact, it's a function that can be specialized to any Testable type -- and then only takes values of that type! This difference explains yet another reason the original test function didn't work. You can't have multiple patterns with variables at different types, because the function only ever works on a single type at a time.
The ideas behind the classes NamedType and Testable above can be generalized a bit; if you do, you get the Typeable class suggested by hammar above.
I think now I've rambled more than enough, and likely confused more things than I've clarified, but leave me a comment saying which parts were unclear, and I'll do my best.
Is there a function that returns the type of an algebraic parameter (a 'show' for types)?
I think Data.Typeable may be what you're looking for.
Prelude> :m + Data.Typeable
Prelude Data.Typeable> typeOf (1 :: Int)
Int
Prelude Data.Typeable> typeOf (1 :: Integer)
Integer
Note that this will not work on any type, just those which have a Typeable instance.
Using the extension DeriveDataTypeable, you can have the compiler automatically derive these for your own types:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Typeable
data Foo = Bar
deriving Typeable
*Main> typeOf Bar
Main.Foo
I didn't quite get what you're trying to do in the second half of your question, but hopefully this should be of some help.

Resources