Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kinds of types in functions

Tags:

haskell

Take the following code:

{-# LANGUAGE KindSignatures, DataKinds #-}

data Nat = O | S Nat

class NatToInt (n :: Nat) where
    natToInt :: n -> Int

instance NatToInt O where
    natToInt _ = 0

instance (NatToInt n) => NatToInt (S n) where
    natToInt _ = 1 + natToInt (undefined :: n)

GHC informs us that it expects an OpenKind in the type specification of natToInt instead of a Nat and thus refuses to compile. This can be remedied by some kind casting:

data NatToOpen :: Nat -> *

and then replacing n with NatToOpen n in t the natToInt-s.

Question 1: is there some way to specify kinds other than * in any function without using type-level wrappers?

Question 2: It appears to me that non-class functions will happily work with types of any kind, for example:

foo :: (a :: *) -> (a :: *)
foo = id

bar = foo (S O)

but inside classes the compiler will complain about kind mismatches, as I described above. Why is that? It doesn't seem that non-class functions are properly polymorphic in kinds, because above I actually specified *, and it still works with Nat-s, as if the kinds were simply ignored.

like image 681
András Kovács Avatar asked May 03 '13 12:05

András Kovács


People also ask

What are the 8 basic types of functions?

The eight types are linear, power, quadratic, polynomial, rational, exponential, logarithmic, and sinusoidal.

What are the different types of functions explain?

Ans. 2 The different types of functions are as follows: many to one function, one to one function, onto function, one and onto function, constant function, the identity function, quadratic function, polynomial function, modulus function, rational function, signum function, greatest integer function and so on.

What are the 2 main classification of function?

Two types of algebraic functions are rational functions and root functions. are rational functions. A root function is a power function of the form f(x)=x1/n, where n is a positive integer greater than one. For example, f(x)=x1/2=√x is the square-root function and g(x)=x1/3=3√x is the cube-root function.


1 Answers

Values always have types of kind * (possibly with some weird exceptions involving unboxing?), so there's nothing you can apply a function to or take as an argument that would have some other kind.

In your final example, you're applying foo to the unlifted version of Nat: the values are S and O, and their type is Nat, which has kind *. In the class definition, you give Nat as a kind using a signature, which means the lifted version, where S and O are types.

The NatToOpen type is just using phantom types in the usual way, but with a phantom type parameter of a non-* kind.

This distinction is not new with DataKinds, either. For example, there are no values whose type is Maybe :: * -> *, as distinct from the type forall a. Maybe a :: *, which is the type of Nothing.

like image 157
C. A. McCann Avatar answered Oct 12 '22 00:10

C. A. McCann