Haskell Bindable entities? - haskell

I saw that, in the book, Programming Language Design Concepts by John Wiley, 2004, there is a definition for bindables:
"A bindable entity is one that may be bound to an identifier.
Programming languages vary in the kinds of entity that are bindable:
• C’s bindable entities are types, variables, and function procedures.
• JAVA’s bindable entities are values, local variables, instance and
class variables, methods, classes, and packages.
• ADA’s bindable entities include types, values, variables,
procedures, exceptions, packages, and tasks."
I'm curious, which bindable entities are in Haskell?

Haskell has three namespaces, one each for runtime computations, types, and modules.
Any term representing a runtime computation may be named in the computation namespace. data and newtype declarations create new names in the computation namespace for constructing values of their new type and, if record syntax is used, for selecting fields from the new type. class declarations create new names in the computation namespace for their methods.
Any monomorphic type may be named in the type namespace with a type declaration (see comments below for my predictions on confusing subtleties in this statement). data and newtype declarations create new names in the type namespace for constructing the type they declare. class declarations create new names in the type namespace for the constraint they create.
module declarations create new names in the module namespace.
GHC extends Haskell, adding a variety of new ways to bind names (almost all in the type namespace); a comprehensive list is probably too large for this format but the manual is excellent and covers them all.
Now, to the subtleties of type. One confusion that I predict will arise is this: I say only monomorphic types may be named. But one may object that I can certainly write, e.g.
type TypeOfIdMono a = a -> a
id :: TypeOfIdMono a
and that looks like it has named a polymorphic type. I claim that Haskell's penchant for making foralls implicit has instead confused the issue, and that TypeOfId a is in fact monomorphic. With explicit foralls, this has been written:
type TypeOfIdMono a = a -> a
id :: forall a. TypeOfIdMono a
That is: we have not actually named id's type here, but rather the type of a monomorphic function which only operates on as. id says additionally that the caller gets to choose a -- that is, that the function is polymorphic. Compare this declaration, which is not allowed in standard Haskell (though is available via GHC extensions, as alluded to above):
type TypeOfIdPoly = forall a. a -> a
id :: TypeOfIdPoly
Here we really have named a polymorphic type.
In short: one can and should distinguish between three orthogonal concepts: "parameterized types" (e.g. TypeOfIdMono which expects an additional argument), types which mention a type variable (e.g. TypeOfIdMono a), and polymorphic types (e.g. TypeOfIdPoly) which necessarily have a forall.

Related

Meaning of "=" in type declaration in Hashkell

As I learn Haskell, I can't help but try to understand everything from a formal point of view. After all this is the theoretical coherence I came to look for as a Scala Programmer.
One thing that does compute well in my mind, is fitting the meaning of type declaration in the overraching theory of lambda calculus and everything is an expression. Yes there is Binding, but Binding does not work with type declaration either.
Example
data DataType a = Data a | Datum
Question:
What is the meaning of = here? If it was the declaration of a function, then on the rhs we would get an expression reducible to an irreducible value or another expression (i.e. returning a function). This is not what we have above.
My confusion
We have a type function in DataType a, and Data Constructor a.k.a Value Constructor in Data a and Datum. Clearly a type is not equal to a value, one is at the term level and the other at the type level. Not the same space at all. However it might work to follow the pronunciation provided here https://wiki.haskell.org/Pronunciation. = is pronounced is. As in a DataType is those values. But that is a stretch. because it is not the same semantic as for a function declaration. Hence I'm puzzled. A Type Level function equal a value level function makes no sense to me.
My question reformulated differently so to explain what i am looking for
So in a sense, I would like to understand the semantic of a data declaration and where does it fit in everything is an expression (Haskell theoretical framework) ?
Clarifying the difference with Binding. Generally speaking, when talking about binding, can we say it is an expression of type Unit ? Otherwise, what is it, and what is the type of it, and where does it fit in lambda calculus or whatever we should call the theoretical framework that backs Haskell ?
I think the simplest answer here is that = doesn’t have any one meaning in particular — it is simply the syntax which the Haskell designers decided to use for data types. There is no particular relationship between the = used in function definitions and the = used in ADT definitions; both constructions are used to declare something on the LHS using some sort of specification on the RHS, but that’s about it. The two constructions have more differences than similarities.
As it happens, modern Haskell doesn’t necessarily require the use of = when defining an ADT. The GADTSyntax and GADTs GHCI language extensions enable ‘GADT syntax’, which is an alternate method to define ADTs. It looks like this:
data DataType a where
Data :: a -> DataType a
Datum :: DataType a
This illustrates that the use of = is not necessarily a mandatory part of type declarations: it is simply one convention amongst many.
(As to why the Haskell designers chose to use the convention with =, I’m not entirely sure. Possibly it might have been by analogy with type synonyms, like type Synonym = Maybe Int, in which = does have similarities to its use in function definitions, in that the RHS expresses a type which is then assigned the name on the LHS.)
Since you mentioned you are a Scala programmer, here is what DataType might look like in Scala:
sealed trait DataType[+A]
case class Data[A](a: A) extends DataType[A]
object Datum extends DataType[Nothing]
I read your Haskell code as "A DataType a can be either a Data a or Datum". DataType is a type constructor, whereas Data is a value constructor and Datum is a value. You can think of Data as a function Data :: a -> DataType a, and Datum as something like Datum :: forall a. DataType a (imagine the names were lowercase). The RHS tells you which functions you can use to get a value of type LHS.

How to write a type instance for a compound type having existentially quantified type variables?

I have a typeclass with an associated type:
class Foo a where
type Bar a :: *
...
Now, I'd like to instance this class for a compound type containing existentially quantified type variables:
data Blat = forall a. Blat a
instance Foo Blat where
type Bar Blat = ???
In my actual application, the "???" needs to make use of the existentially hidden "a" in Blat a, in order for the program logic to be correct.
Is this doable in Haskell?
If so, how?
===
In response to #leftaroundabout 's request for full disclosure of my original intent:
I'm trying to build representations of types, using only a small set of "primitives" (i.e. - unit, sum, and product).
And, for compound types, I'd like to enlist the help of the pre-existing representation instances for the fields making up the new type.
For explicitly parameterized field types this is straightforward.
However, I'd like to be able to do it for field types using existentially hidden type parameters, also.
It can't be done. An existentially quantified type is only chosen at runtime, whereas a type family instantiation (associated or otherwise) must be fixed at compile time.
This is probably an XY problem. Instead of an associated type family, you should deal with the type information in some other way, but it would require knowledge of the problem you're trying to solve to say how.

What does instance mean in Haskell?

In object-oriented languages (e.g; Java and Python) we can make objects/instances from classes.
In Haskell we can make instances from type-classes, ex:
data ShirtSize = S | M | L -- Here ShirtSize is a enum data-type
class MyEq a where
(==) :: a -> a -> Bool
instance MyEq ShirtSize where -- Here ShirtSize is an instance of the MyEq type-class
S == S = True
M == M = True
L == L = True
_ == _ = False
My question is:
What does instance mean in haskell?
In java we can make instances from classes, but in haskell it seems like instances are types (like ShirtSize) which you can apply type-class functions on (e.g the (==) function from MyEq). Am I right? and also what is an instance in Haskell compared to an instance/object in Java?
In Java, the class system is a way to group similar objects. An instance of a class is an individual object which belongs to that class.
In Haskell, the class system is (roughly speaking) a way to group similar types. (This is the reason we call them "type classes"). An instance of a class is an individual type which belongs to that class. (That is, until you start considering multiparametric type classes).
Incidentally, a Haskell (monoparametric) class somewhat resembles a Java interface and, by extension, a Java class. Or perhaps a Haskell instance resembles Java class. It's better to view this as a coincidence. Approach the term keeping its mathematical origins in mind. A class is just a bunch of things that belong together, and an instance is one of these things.
If you're interested in explanation of type classes and difference from Java interfaces you should read this post by <❤>. It also explains instances as well.
As for me, I look at instance as connection between data type and interface. data contains some information, class contains methods. data is about data (sorry for tautology) and class is about behavior. When you look at data type you don't see what you can do with it, instead you see what it stores. When you look at class you see what type should be able to do, you don't care what it stores internally. In real programming you actually care about details of implementations and how methods implemented using specific data. So instance just shows you relation between some data and some behavior — how this behavior implemented using given data.
In case you're interested more in model of type classes then read this blog post: http://www.haskellforall.com/2012/05/scrap-your-type-classes.html
You can look at instances as a values! It might blow your mind if you face such definition first time.
In some dependently type languages instances are really values that you can pass to other functions. Take a look at this question:
In Idris, is "Eq a" a type, and can I supply a value for it?
it seems like instances are types (like ShirtSize) which you
can apply type-class functions on (e.g the (==) function from MyEq)
Absolutely correct.
In Haskell a type is a defined structure of data. Every value that exists in Haskell code has a defined type. And a type can be made an instance of a class, which means... actually, hold that thought. I want to talk about functions.
Functions have type signatures, defining which type(s) they can be used on. If a function is defined to work on a particular type, then the function can be used on any value that has that type. If a function is defined to work on a particular class, then it can be used on any value of any of the types that are instances of that class.
When you define a class you describe some minimal set of functions (eg == in your example) which have to be implemented for all the types that want to be instances of that class. The class defines names and signatures for those functions, and that definition means those names and signatures are fixed. They will be the same for every instance of the class.
But the implementations aren't fixed by the class. They can be different for different types. We make a type into an instance of a class by writing an instance statement, in which we can define how those functions will work. If the class provides a default implementation of a function, then the different instance types can override the default and have their own definitions. And if there is no default, then the instance types must have their own definitions.
Now you have a minimal set of functions which can be called with any value of any of the types. And you can write more functions that work by calling those functions, and build up from there.
The idea is really useful, but IMHO the terminology is awful. Saying that these types are instances of a class makes it sound as if they're subtypes or child types, inheriting properties from parent types. But it's not like that at all. Being an instance of a class is like being a member of a club. Lots of different, unrelated types can all be instances of the same class. And one type can be an instance of lots of different unrelated classes, all at the same time.
In Rust, they have the same idea, but with the word 'trait' instead of 'class'. Instead of saying "this type is an instance of that class", they would say "this type implements that trait". I think that gets the idea across much better.

Haskell terminology: meaning of type vs. data type, are they synonyms?

I'm reading the book: Haskell School of Expression and on page 56, at the beginning of chapter 5, I read the terms "polymorphic data types" and "polymorphic types".
Are these two terms refer to the same concept?
Are they synonyms ?
Or is there any difference between the two? If yes, what?
A type (in Haskell) is a piece of syntax which can meaningfully be put right of :: to classify an expression left of ::. Each syntactic component of a type is itself classified by a kind, where the kind of types (which classify expressions) is *. Some people are happy to use the word "type" to refer to any component of the type syntax, whether or not its kind allows it to classify expressions.
The syntax of types can be extended by various declaration forms.
A type synonym, e.g., type Foo x y z = [x] -> IO (y, z), adds type components of fully applied form Foo x y z, which expand macro-fashion in accordance with their defining equation.
A data declaration, e.g., data Goo x y z = ThisGoo x | ThatGoo (Goo y z x) introduces a fresh type constructor symbol Goo to the syntax of types, which is used to build the types which classify values generated by the data constructors, here ThisGoo and ThatGoo.
A newtype declaration, e.g., newtype Noo x y z = MkNoo (x, [y], z) makes a copy of an existing type which is distinguished from the original in the syntax of types.
A type is polymorphic if it contains type variables which can be substituted with other type components: the values classified by polymorphic types can be specialized to any substitution instance of the type variables. E.g. append (++) :: [a] -> [a] -> [a] works on lists whose elements have the same type, but any type will do. Values with polymorphic types are often referred to as "polymorphic values".
Sometimes, "data type" is used to mean, quite simply, a type introduced by a data declaration. In this sense, all data types are types, but not all types are data types. Examples of types which are not data types include IO () and Int -> Int. Also, Int is not a data type in this sense: it is a hardwired primitive type. For the avoidance of doubt, some people call these types algebraic data types, because the constructors give an algebra, meaning "a bunch of operations for building values by combining other values". A "polymorphic data type" is a data type with type variables in it, such as [(a, Bool)], by contrast with [Int]. Sometimes people talk about "declaring a polymorphic data type" or say things like "Maybe is a polymorphic data type" when they really just mean that the type constructor has parameters (and can thus be used to form polymorphic types): pedantically, one does declare a polymorphic data type, but not any old polymorphic datatype, rather a type constructor applied to formal parameters).
Of course, all first-class values classified by types are in some sense "data", and in Haskell, types are not used to classify anything which is not a first-class value, so in that looser sense, every "type" is a "data type". The distinction becomes more meaningful in languages where there are things other than data which have types (e.g., methods in Java).
Informal usage is often somewhere in the middle and not very well defined. People are often driving at some sort of distinction between functions or processes and the sort of stuff (the "data") on which they operate. Or they might think of data as being "understood in terms of the way they're made" (and exposing their representation, e.g. by pattern matching) rather than "understood in terms of the way they're used". This last usage of "data" sits a little uncomfortably with the notion of an abstract data type, being a type which hides the representation of the underlying stuff. Representation-hiding abstract data types thus contrast rather strongly with representation-exposing algebraic data types, which is why it is rather unfortunate that "ADT" is casually used as an abbreviation for both.
The upshot, I'm afraid, is vague.
In this case, data type and type are synonymous. However, I will admit that confusion can arise because Haskell has two keywords data and type that perform two very different functions. To try to keep the distinction clear, it's important to be mindful of the context. Whenever you're talking about the types in a signature or types in general, the terms "data types" and "types" almost always refer to the same thing. Whenever you're talking about declaring types in code, there can be a difference.
A type declared with data is a new, user-defined type, so you can do things like
data Status = Ready | NotReady | Exploded
Where Ready, NotReady and Exploded are new constructors not included in Haskell.
On the other hand, there is the type keyword that simply creates an alias to an existing type:
type Status = String
ready, notReady, exploded :: Status
ready = "Ready"
notReady = "NotReady"
exploded = "Exploded"
Here, the Status is simply an alias for String, and anywhere you use String you can use a Status and vice-versa. There aren't any constructors, just pre-built values to use. This approach is far less safe and if you use something like this you will run into bugs at some point. type declarations are commonly used to make certain arguments more clear about what they're for, such as
type FilePath = String
This is a built-in alias in GHC, and if you see a function
doSomething :: FilePath -> IO ()
Then you know immediately to pass it a file name, compared to
doSomething :: String -> IO ()
You have no idea what this function does, other than "something". They're also commonly used to reduce typing, such as:
type Point = (Double, Double)
Now you can use Point instead of (Double, Double) in your type signatures, which is shorter to write and more readable.
To summarize, data declares an entirely new type, completely custom just for you, and type should be renamed alias so that people stop getting confused about them when they first approach Haskell.
type and data type refers to the same concept, and so are polymorphic type and polymorphic data type.
To illustrate a case where both phrases may be used altogether (without any difference on meaning), consider this expression
data Maybe a = Just a | Nothing
I can say that I just defined a polymorphic data type Maybe, with polymorphic type parameter a.

What symbol namespaces are there in Haskell?

I'm trying to reduce my confusion about Haskell's syntax and would like to find out what the separate namespaces are in Haskell.
Namespaces meaning syntactical namespaces corresponding to the various symbols tables the compiler manages, not name scopes defined in code.
For example:
Value names (like function names)
Data constructors
Type constructors
Type parameters (in type definitions)
instances ?
...?
I'm interested because I'm having trouble reading Haskell code (definitely more than with any other language) because I frequently have a hard time figuring out what exactly I'm looking at (especially with data/type constructors/type declarations).
Haskell seems to reuse a handful of syntactical constructs (esp. <name> <name> ...) in many places and relies on context - just turns out that the compiler is a lot better at this than me...
The Haskell Report §1.4 says
There are six kinds of names in Haskell: those for variables and
constructors denote values; those for type variables, type
constructors, and type classes refer to entities related to the type
system; and module names refer to modules. There are two constraints
on naming:
Names for variables and type variables are identifiers beginning with lowercase letters or underscore; the other four kinds of names
are identifiers beginning with uppercase letters.
An identifier must not be used as the name of a type constructor and a class in the same scope.
These are the only constraints; for example, Int may simultaneously be
the name of a module, class, and constructor within a single scope.
The confusion can be avoided if you make sure you understand what you are reading:
an expression: here every upper case name is a data constructor or a qualified variable or constructor whereas lower case are values
a type: here every upper case name is a type constructor or class name, whereas lower case names are type variables.

Resources