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

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

Related

Multiple types for f in this picture?

https://youtu.be/brE_dyedGm0?t=1362
data T a where
T1 :: Bool -> T Bool
T2 :: T a
f x y = case x of
T1 x -> True
T2 -> y
Simon is saying that f could be typed as T a -> a -> a, but I would think the return value MUST be a Bool since that is an explicit result in a branch of the case expression. This is in regards to Haskell GADTs. Why is this the case?
This is kind of the whole point of GADTs. Matching on a constructor can cause additional type information to come into scope.
Let's look at what happens when GHC checks the following definition:
f :: T a -> a -> a
f x y = case x of
T1 _ -> True
T2 -> y
Let's look at the T2 case first, just to get it out of the way. y and the result have the same type, and T2 is polymorphic, so you can declare its type is also T a. All good.
Then comes the trickier case. Note that I removed the binding of the name x inside the case as the shadowing might be confusing, the inner value isn't used, and it doesn't change anything in the explanation. When you match on a GADT constructor like T1, one that explicitly sets a type variable, it introduces additional constraints inside that branch which add that type information. In this case, matching on T1 introduces a (a ~ Bool) constraint. This type equality says that a and Bool match each other. Therefore the literal True with type Bool matches the a written in the type signature. y isn't used, so the branch is consistent with T a -> a -> a.
So it all matches up. T a -> a -> a is a valid type for that definition. But as Simon is saying, it's ambiguous. T a -> Bool -> Bool is also a valid type for that definition. Neither one is more general than the other, so the definition doesn't have a principle type. So the definition is rejected unless a type is provided, because inference cannot pick a single most-correct type for it.
A value of type T a with a different from Bool can never have the form T1 x (since that has only type T Bool).
Hence, in such case, the T1 x branch in the case becomes inaccessible and can be ignored during type checking/inference.
More concretely: GADTs allow the type checker to assume type-level equations during pattern matching, and exploit such equations later on. When checking
f :: T a -> a -> a
f x y = case x of
T1 x -> True
T2 -> y
the type checker performs the following reasoning:
f :: T a -> a -> a
f x y = case x of
T1 x -> -- assume: a ~ Bool
True -- has type Bool, hence it has also type a
T2 -> -- assume: a~a (pointless)
y -- has type a
Thanks to GADTs, both branches of the case have type a, hence the whole case expression has type a and the function definition type checks.
More generally, when x :: T A and the GADT constructor was defined as K :: ... -> T B then, when type checking we can make the following assumption:
case x of
K ... -> -- assume: A ~ B
Note that A and B can be types involving type variables (as in a~Bool above), so that allows one obtain useful information about them and exploit it later on.

Abstract data types in a type class definition

I'm trying to understand what's happening with the type s below:
class A a where
f :: a -> s
data X = X
instance A X where
f x = "anything"
I expected this to work, thinking that since type s isn't bound to anything, it could be anything. But the compiler says that it "Couldn't match expected type ‘s’ with actual type ‘[Char]’", as if type s was a fixed type like Int, Char…
So my second interpretation was to say that, since we don't know anything about s in the type class declaration, we cannot tell when making X an instance of A if the return value of the function f we give matches type s or not. But there are type classes that use abstract data types that are not bound to anything without problems, like Functor:
class Functor f where
fmap :: (a -> b) -> f a -> f b
Why is the type s above a problem when types a and b here aren't?
You're trying to express this:
f :: a -> ∃s . s
...but what the signature you've written says is actually
f :: a -> ∀s . s
What does all of that mean?
The existential type ∃s . s means, the functions may return a value of some type, i.e. “there exists a type s such that the function returns an s value”.This is not supported by the Haskell language, because it turns out to be pretty useless.
The universal type ∀s . s means, the function is able to produce a value of any type, i.e. “for all types s, the function can return an s value”.
The latter is very useful; fmap is actually a good example: that function works, no matter what types a and b are, and the user is always guaranteed that the result will actually have the desired type, namely f b.
But that means you can't just pick some particular type in the implementation, like you did with String. ...Well, actually you can do that, but only by wrapping the existential in a data type:
{-# LANGUAGE ExistentialQuantification, UnicodeSyntax #-}
data Anything = ∀ s . Anything s
class A a where
f :: a -> Anything
instance A X where
f x = Anything "anything"
...but as I said, this is almost completely useless, because when somebody wants to use that instance they'll have no way to know what particular type the wrapped result value has. And there is nothing you can do with a value of completely unknown type.

How can I write self-application function in Haskell?

I tried following code, but it generates type errors.
sa f = f f
• Occurs check: cannot construct the infinite type: t ~ t -> t1
• In the first argument of ‘f’, namely ‘f’
In the expression: f f
In an equation for ‘sa’: sa f = f f
• Relevant bindings include
f :: t -> t1
(bound at fp-through-lambda-calculus-michaelson.hs:9:4)
sa :: (t -> t1) -> t1
(bound at fp-through-lambda-calculus-michaelson.hs:9:1)
Use a newtype to construct the infinite type.
newtype Eventually a = NotYet (Eventually a -> a)
sa :: Eventually a -> a
sa eventually#(NotYet f) = f eventually
In GHC, eventually and f will be the same object in memory.
I don't think there is a single self-application function that will work for all terms in Haskell. Self-application is a peculiar thing in typed lambda calculus, which will often evade typing. This is related to the fact that with self-application we can express the fixed-point combinator, which introduces inconsistencies into the type system when viewed as a logical system (see Curry-Howard correspondence).
You asked about applying it to the id function. In the self application id id, the two ids have different types. More explicitly it's (id :: (A -> A) -> (A -> A)) (id :: A -> A) (for any type A). We could make a self-application specifically designed for the id function:
sa :: (forall a. a -> a) -> b -> b
sa f = f f
ghci> :t sa id
sa id :: b -> b
which works just fine, but is rather limited by its type.
Using RankNTypes you can make families of self-application functions like this, but you're not going to be able to make a general self-application function such that sa t will be well-typed iff t t is well-typed (at least not in System Fω ("F-omega"), which GHC's core calculus is based on).
The reason, if you work it out formally (probably), is that then we could get sa sa, which has no normal form, and Fω is known to be normalizing (until we add fix of course).
This is because the untyped lambda calculus is in some way more powerful than Haskell. Or, to put it differently, the untyped lambda calculus has no type system. Thus, it has no sound type system. Whereas Haskell does have one.
This shows up not only with self application, but in any cases where infinite types are involved. Try this, for example:
i x = x
s f g x = f x (g x)
s i i
It is astonishing how the type system finds out that the seemingly harmless expresion s i i should not be allowed with a sound type system. Because, if it were allowed, self application would be possible.

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 Justification for the type of f x = f x in Haskell is there?

Haskell gives f x = f x the type of t1 -> t, but could someone explain why?
And, is it possible for any other, nonequivalent function to have this same type?
Okay, starting from the function definition f x = f x, let's step through and see what we can deduce about the type of f.
Start with a completely unspecified type variable, a. Can we deduce more than that? Yes, we observe that f is a function taking one argument, so we can change a into a function between two unknown type variables, which we'll call b -> c. Whatever type b stands for is the type of the argument x, and whatever type c stands for must be the type of the right-hand side of the definition.
What can we figure out about the right-hand side? Well, we have f, which is a recursive reference to the function we're defining, so its type is still b -> c, where both type variables are the same as for the definition of f. We also have x, which is a variable bound within the definition of f and has type b. Applying f to x type checks, because they're sharing the same unknown type b, and the result is c.
At this point everything fits together and with no other restrictions, we can make the type variables "official", resulting in a final type of b -> c where both variables are the usual, implicitly universally quantified type variables in Haskell.
In other words, f is a function that takes an argument of any type and returns a value of any type. How can it return any possible type? It can't, and we can observe that evaluating it produces only an infinite recursion.
For the same reason, any function with the same type will be "equivalent" in the sense of never returning when evaluated.
An even more direct version is to remove the argument entirely:
foo :: a
foo = foo
...which is also universally quantified and represents a value of any type. This is pretty much equivalent to undefined.
f x = undefined
has the (alpha) equivalent type f :: t -> a.
If you're curious, Haskell's type system is derived from Hindley–Milner. Informally, the typechecker starts off with the most permissive types for everything, and unifies the various constraints until what remains is consistent (or not). In this case, the most general type is f :: t1 -> t, and there's no additional constraints.
Compare to
f x = f (f x)
which has inferred type f :: t -> t, due to unifying the types of the argument of f on the LHS and the argument to the outer f on the RHS.

Resources