What is the bottom type? - lambda-calculus

In wikipedia, the bottom type is simply defined as "the type that has no values". However, if b is this empty type, then the product type (b,b) has no values either, but seems different from b. I agree bottom is uninhabited, but I don't think this property suffices to define it.
By the Curry-Howard correspondence, bottom is associated to mathematical falsity. Now there is a logical principle stating that from False follows any proposition. By Curry-Howard, that means the type forall a. bottom -> a is inhabited, ie there exists a family of functions f :: forall a. bottom -> a.
What are those functions f ? Do they help define bottom, maybe as the infinite product of all types forall a. a ?

In Math
Bottom is a type that has no value. That is : any empty type can play the bottom role.
Those f :: forall a . Bottom -> a functions are the empty functions. "empty" in the set theoretical definition of functions.
In Programming
Dedicating a concrete empty type to have it as bottom by a programming language base library is for convenience. Readability and compatibility of code benefits from everyone using the same empty type as bottom.
In Haskell
Let us refer to them with the more friendly names "Bottom" -> "Void", "f" -> "absurd".
{-# LANGUAGE EmptyDataDecls #-}
data Void
This definition does not contain any constructors => an instance of it can not be created => it is empty.
absurd :: Bottom -> a
absurd = \ case {}
In the case expression we do not have to handle any cases because there are none.
They are already defined in package base

Related

Is F# Constructed Type syntax special?

I was curious about F#'s "constructed type" syntax. It's documented here.
type-argument generic-type-name
or
generic-type-name
With the following examples:
int option
string list
int ref
option<int>
list<string>
ref<int>
Dictionary<int, string>
I was curious if there's anything special about the "backwards" syntax, with the parameter before the type, or if it's just sugar for generic types with one parameter. The following is valid:
type 'a MyOption = // MyOption<'a> also works
| MySome of 'a
| MyNone
But I could not get it to work with multiple type parameters. Why do F# developers prefer this syntax for types with one parameter? Is it possible or desirable to make it work with two?
The backwards syntax is a legacy from OCaml. Personally, I never use it. If you really want to, you can make it work with multiple type arguments like this:
type MyMap = (int, string) Map
However, this generates a pointed warning (that might soon become an error):
This construct is for ML compatibility. The syntax '(typ,...,typ) ident' is not used in F# code. Consider using 'ident<typ,...,typ>' instead. You can disable this warning by using '--mlcompatibility' or '--nowarn:62'.
Bottom line, I would recommend always using .NET syntax instead: MyOption<'a> instead of 'a MyOption.
Why do F# developers prefer this syntax for types with one parameter?
Not all of us do. I love F# and am in awe of it, but find the OCaml style distracting.
It gets especially confusing when the two styles are mixed - compare the readability of Async<Result<int,string list>> list with that of List<Async<Result<int,List<string>>>>.
Here is a thread with some arguments from both sides from fslang suggestions, which I think led to the deprecation of OCaml-style for everything but list, option and a few others.
I find it regrettable that the OCaml style is specified as the preferred option (for these types) in the various style guides, and used throughout the core libraries, while there is such a strong drive to make the language more accessible to newcomers. It definitely adds to the learning curve, as documented in this question,
and here,
here,
here,
here,
here.
Is it possible or desirable to make [OCaml style naming] work with two [type parameters]?
I think a better question is: "Is it possible to only use .NET style?".
Unfortunately the tooling shows types the way they are declared, and the core libraries consistently use OCaml style. I have asked Rider about always showing declarations .NET style in code vision, who referred me to FSharp compiler services. I have not (yet) investigated that avenue further.
In our own code we have taken to overriding the OCaml signatures of functions that ship with F# and other libraries as we come across them, for example:
[<AutoOpen>]
module NoCaml =
module List =
/// Returns a new collection containing only the elements of the collection for which the given predicate returns "true"
let filter = List.filter : ('a -> bool) -> List<'a> -> List<'a>
/// val groupBy : projection:('T -> 'Key) -> list:'T list -> ('Key * 'T list) list (requires equality and equality) 'T is 'a 'Key is 'b Applies a key-generating function to each element of a list and yields a list of unique keys. Each unique key contains a list of all elements that match to this key.
let groupBy = List.groupBy : ('a -> 'b) -> List<'a> -> List<'b * List<'a>>
// etc.
This solves the problem in almost all cases (some exceptions like list construction using [] remain, and need to be overridden at the point of declaration).
I'm not sure what influence this has on performance at runtime - hopefully the extra function calls are optimised away.

fat arrow in Idris

I hope this question is appropriate for this site, it's just about the choice of concrete syntax in Idris compared to Haskell, since both are very similar. I guess it's not that important, but I'm very curious about it. Idris uses => for some cases where Haskell uses ->. So far I've seen that Idris only uses -> in function types and => for other things like lambdas and case _ of. Did this choice come from realizing that it's useful in practice to have a clear syntactical distinction between these use cases? Is it just an arbitrary cosmetic choice and I'm overthinking it?
Well, in Haskell, type signatures and values are in different namespaces, so something defined in one is at no risk of clashing with something in the other. In Idris, types and values occupy the same namespace, which is why you don't see e.g. data Foo = Foo as you would in Haskell, but rather, data Foo = MkFoo - the type is called Foo, and the constructor is called MkFoo, as there is already a value (the type Foo), bound to the name Foo, e.g. data Pair = MkPair http://docs.idris-lang.org/en/latest/tutorial/typesfuns.html#tuples
So it's probably for the best it didn't try to use the arrow used to construct the type of functions, with the arrow used for lambdas - those are rather different things. You can combine them with e.g. the (Int -> Int) (\x => x).
I think it is because they interpret the -> symbol differently.
From Wikipedia:
A => B means if A is true then B is also true; if A is false then nothing is said about B
which seems right for case expressions, and
-> may mean the same as =>, or it may have the meaning for functions given below
which is
f: X -> Y means the function f maps the set X into the set Y
So my guess is that Idris just uses -> for the narrow second meaning, i.e. for mapping one type to another in type signatures, whereas Haskell uses the broader interpretation, where it means the same as =>.

Game Data Structure in OCaml

I am currently working on a game / simulation of a computer like logistics system (like the minecraft mod applied energestics).
The main part of the game is the 2d grid of blocks.
All the blocks have common properties like a position.
But then there are supposed to be different kinds of Blocks like:
Item-Containers,
Input and Export Busses,
etc.
In an imperative object-oriented language (like Java) I would implement this with:
a main block class
with the common properties like position
then have sub classes
that inherit from the block class
These subclasses would implement the different properties of the different block types.
In ocaml I am a litle bit lost.
I could create objects which inherit but this does not work Like in Java.
For example:
I cant put objects of different subclasses in one list together.
I also wanted to approach the data structure differently by separating data from logic. I would not add methods to the objects. I tried using records instead of objects.
I don't know how to implement the different block types.
I tried using custom data types like this:
type blockType = Container | Input | Output | Air
type block = {blockType :blockType; pos :int * int}
I struggled to add the individual additional properties. I tried to add an entity field to the block record type which would hold the additional properties:
type entity = Container of inventory | OutputEntity of facing | InputEntity of facing | NoEntity
(Where inventory and facing are also custom types)
This solution doesn't really feel fitting.
One problem I have is that there are logic operations I want to perform on blocks of type Input and Output. I have to repeat code like this:
let rotateBlock block =
match block.blockType with
| Input -> {block with entity = nextDirection block.entity}
| Output -> {block with entity = nextDirection block.entity}
| _ -> block
That's not that bad with two types but I plan to add much more so it is a big negative in terms of scalability.
Another point of critism of this kind of structure is that it is a litle bit inconsistent. I use a field in the record to implement the different types on the block level and multiple constructors on the entity level. I did it to be able to access the positon of every block easily with block.pos instead of using pattern matching.
I am not really happy with this solution.
Request
I hope somebody can point me in the right direction regarding the data structure.
You're trying to satisfy competing goals. You can't have both, a rigid static model of blocks and a dynamic extensible block type. So you need to choose. Fortunately, OCaml provides solutions for both, and even for something between, but as always for the middle-ground solutions, they kind of bad in both. So let's try.
Rigid static hierarchy using ADT
We can use sum types to represent a static hierarchy of objects. In this case, it would be easy for us to add new methods, but hard to add new types of objects. As the base type, we will use a polymorphic record, that is parametrized with a concrete block type (the concrete block type could be polymorphic itself, and this will allow us to build the third layer of hierarchy and so on).
type pos = {x : int; y : int}
type 'a block = {pos : pos; info = 'a}
type block_info = Container of container | Input of facing | Air | Solid
where info is an additional concrete block specific payload, i.e., a value of type block_info. This solution allows us to write polymorphic functions that accept different blocks, e.g.,
let distance b1 b2 =
sqrt ((float (b1.x - b2.x))**2. + (float (b1.y - b2.y)) **2.)
The distance function has type 'a blk -> 'b blk -> float and will compute the distance between two blocks of any type.
This solution has several drawbacks:
Hard to extend. Adding a new kind of block is hard, you basically need to design beforehand what blocks do you need and hope that you do not need to add a new block in the future. It looks like that you're expecting that you will need to add new block types, so this solution might not suit you. However, I believe that you will actually need a very small number of block kinds if you will treat each block as a syntactical element of the world grammar, you will soon notice that the minimal set of block kinds is quite small. Especially, if you will make your blocks recursive, i.e., if you will allow block composition (i.e., mixtures of different blocks in the same block).
You can't put blocks of different kinds in the same container. Because to do this, you need to forget the type of block. If you will do this, you will eventually end up with a container of positions. We will try to alleviate this in our middle-ground solution by using existential types.
Your type model doesn't impose right constraints. The world constraint is that the world is composed of blocks, and each coordinate either has a block or doesn't have one (i.e., it is the void). In your case, two blocks may have the same coordinates.
Not so rigid hierarchy using GADT
We may relax few restrictions of the previous solution, by using existential GADT. The idea of the existential is that you can forget the kind of a block, and later recover it. This is essentially the same as a variant type (or dynamic type in C#). With existentials, you can have an infinite amount of block kinds and even put them all in the same container. Essentially, an existential is defined as a GADT that forgets its type, e.g., the first approximation
type block = Block : block_info -> {pos : pos; info : block_info}
So now we have a unified block type, that is locally quantified with the type of block payload. You may even move further, and make the block_info type extensible, e.g.,
type block_info = ..
type block_info += Air
Instead of building an existential representation by yourself (it's a nice exercise in GADT), you may opt to use some existing libraries. Search for "universal values" or "universals" in the OPAM repositories, there are a couple of solutions.
This solution is more dynamic and allows us to store values of the same type in the same container. The hierarchy is extensible. This comes with a price of course, as now we can't have one single point of definition for a particular method, in fact, method definitions would be scattered around your program (kind of close to the Common Lisp CLOS model). However, this is an expected price for an extensible dynamic system. Also, we lose the static property of our model, so we will use lots of wildcard in pattern matching, and we can't rely on the type system to check that we covered all possible combinations. And the main problem is still there our model is not right.
Not so rigid structure with OO
OCaml has the Object Oriented Layer (hence the name) so you can build classical OO hierarchies. E.g.,
class block x y = object
val x = x
val y = y
method x = x
method y = y
method with_x x = {< x = x >}
method with_y y = {< y = y >}
end
class input_block facing = object
inherit block
val facing = facing
method facing = facing
method with_facing f = {< facing = f >}
end
This solution is essentially close to the first solution, except that your hierarchy is now extensible at the price that the set of methods is now fixed. And although you can put different blocks in the same container by forgetting a concrete type of a block using upcasting, this won't make much sense since OCaml doesn't have the down-cast operator, so you will end up with a container of coordinates. And we still have the same problem - our model is not right.
Dynamic world structure using Flyweights
This solution kills two bunnies at the same time (and I believe that this should be the way how it is implemented in Minecraft). Let's start with the second problem. If you will represent every item in your world with a concrete record that has all attributes of that item you will end up with lots of duplicates and extreme memory consumption. That's why in real-world applications a pattern called Flyweight is used. So, if you think about scalability you will still end up in using this approach. The idea of the Flyweight pattern is that your objects share attributes by using finite mapping, and objects itself are represented as identifiers, e.g.,
type block = int
type world = {
map : pos Int.Map.t;
facing : facing Int.Map.t;
air : Int.Set.t;
}
where 'a Int.Map.t is a mapping from int to 'a, and Int.Set.t is a set of integers (I'm using the Core library here).
In fact, you may even decide that you don't need a closed world type, and just have a bunch of finite mappings, where each particular module adds and maintains its own set of mappings. You can use abstract types to store this mapping in a central repository.
You may also consider the following representation of the block type, instead of one integer, you may use two integers. The first integer denotes an identity of a block and the second denotes its equality.
type block = {id : int; eq : int}
The idea is that every block in the game will have a unique id that will distinguish it from other blocks even if they are equal "as two drops of water". And eq will denote structural equality of two blocks, i.e., two blocks with exact same attributes will have the same eq number. This solution is hard to implement if you world structure is not closed though (as in this case the set of attributes is not closed).
The main drawback of this solution is that it is so dynamic that it sorts of leaving the OCaml type system out of work. That's a reasonable penalty, in fact you can't have a dynamic system that is fully verified in static time. (Unless you have a language with dependent types, but this is a completely different story).
To summarize, if I were devising such kind of game, I will use the last solution. Mainly because it scales well to a large number of blocks, thanks to hashconsing (another name for Flyweight). If scalability is not an issue, then I will build a static structure of blocks with different composition operators, e.g.,
type block =
| Regular of regular
| ...
| Compose of compose_kind * block * block
type compose_kind = Horizontal | Vertical | Inplace
And now the world is just a block. This solution is pure mathematical though, and doesn't really scale to larger worlds.
Sounds like fun.
I cant put objects of different subclasses in one list together.
You can actually. Suppose you had lots of different block-objects that
all had a 'decay' method. You could have a function "get me the
decayables" and it could put all those blocks in a list for you, and
you could then at timed intervals iterate over the list and apply the
decay method on each of those blocks. This is all well typed and easy
to do with OCaml's object system. What you can't do is take out a
'decayable' from that list and say, actually, this was always also
an AirBlock, and I want to treat it like a full-fledged AirBlock now,
instead of a decayable.
...
type blockType = Container | Input | Output | Air
You can only have 240 so variants per type. If you plan on having more
blocks than this, an easy way to gain extra space would be to
categorize your blocks and work with e.g. Solid Rock | Liquid Lava
rather than Rock | Lava.
type block = {blockType :blockType; pos :int * int}
What's the position of a block in your inventory? What's the position
of a block that's been mined out of its place in the world, and is
now sort of sitting on the ground, waiting to be picked up? Why not
keep the positions in the array indices or map key that you're using
to represent the locations of blocks in the world? Otherwise you also
have to consider what it means for blocks to have the same position,
or impossible positions.
let rotateBlock block =
match block.blockType with
| Input -> {block with entity = nextDirection block.entity}
| Output -> {block with entity = nextDirection block.entity}
| _ -> block
I don't really follow this input/output stuff, but it seems that in this
function you're interested in some kind of property like "has a next direction
to face, if rotated". Why not name that property and make it what you match on?
type block = {
id : blockType;
burnable : bool;
consumable : bool;
wearable : bodypart option; (* None - not wearable *)
hitpoints : int option; (* None - not destructible *)
oriented : direction option; (* None - doesn't have distinct faces *)
}
let rotateBlock block =
match block.oriented with
| None -> block
| Some dir -> {block with oriented = Some (nextDirection dir)}
let burn block =
match block.burnable, block.hitpoints with
| false, _ | true, None -> block
| true, Some hp when hp > 5 -> { block with hitpoints = Some (hp - 5) }
| true, Some hp -> ash
The block type is interesting because each kind will have different operations.
Item-Containers,
Input and Export Busses,
etc.
type container = { specificinfo : int ; etc ...}
type bus .....
type block =
| Item of position * container
| Bus of position * bus
type inventory = block list
My intuition say me that you can perhaps use GADT for creating the type of the operations on block and implement an evaluator easily for the simulator.
UPDATE
to answer to your comment :
If you have a common information to all your variants, you need to extract them, you can imagine something like :
type block_info =
| Item of specific_item_type ....
| Bus of specific_bus_type
type block = {position:Vector.t ; information : block_info}
let get_block_position b = b.position

Can GADTs (or existentials) without constraints be compiled as tight as untyped ordinary ADTs?

Suppose I have some ADT, like
data Foo = Foo !Int
| Bar (Int->Int) Foo
Now say I want to impose some kind of extra type safety, getting rid of the "magic number type":
{-# LANGUAGE GADTs #-}
newtype Intey a = Intey { getIntey :: Int }
data Foo' a where
Foo :: !(Intey a) -> Foo' a
Bar :: (Intey a -> Intey b) -> Foo' a -> Foo' b
Since b is just a phantom argument within the constructor, has no constraints or anything else, it is basically meaningless – except for the type checker. Can it therefore compile down to the same as Foo, without any performance etc. cost?
You'd need to look at the Core to be absolutely sure, but in general:
newtype has no runtime cost compared to the underlying type. However something like map getIntey will still traverse the list doing nothing.
Types and type parameters themselves are erased during compilation so should also have no runtime cost - this is one of the advantages of static typing. It's only if you use a type class that a runtime value might be passed around.
So in most cases you can expect the same performance, but you may need to be a little careful about operations on containers like lists.
If you restrict yourself to GHC 7.8, then the new coerce function can help with that too.

Unrestricted variable name declaration in Mercury

I would like to declare a data type in Mercury that can have a variable number of values and names. For instance :
type goal ---> pick; give; come.
has three variables/values.
I want something like:
type myplayer ---> de value declaration here.
That's the number of variables are not restricted or fixed.
So I can use myplayer to declare values/variables like v1, v2, v3 and v4. The second time I can use it to declare something like: a, b, c, d, e, z, aa, ab and az.
The number of the values are not restricted and the names are also not fixed.
I am new in Mercury.
As others have said, this is simply impossible in Mercury - which is deliberate.
What you might want though, if you want a type that expresses: v1 v2 v3... etc is:
:- type my_type
----> v(int).
:- func name(my_type) = string.
name(v(Num)) = formst("v%d", [i(Num)]).
The type expresses v of all integers, and the function name can be used to 'pretty-print' values of this type.
What you directly ask for, simply cannot be done. Given
:- type question
---> truth(string, bool)
; blank(string, string)
; multiple(string, string, list(string)).
additional kinds of questions can only be added by extending this type where it is defined, and recompiling the module - and making a lot of other changes, too, as previously deterministic code like
answer(truth(_, yes)) = "true".
answer(truth(_, no)) = "false".
answer(blank(_, A)) = A.
answer(multiple(_, A, _)) = A.
would fail when given your new question type. Being told at compile-time where you've failed to update your program to reflect the addition of a "pick-all-the-right-answers" type of question is a good part of the reason you have a question type at all, instead of say lists of strings [["Are foxes pretty?", "true"], ["Green foxes are ____", "adorable!", "fake", "evidence of animal cruelty"]] for your question bank.
What you ask for cannot be done. However, what you actually want to do -- the end to which you thought 'variable numbers of types' would be an helpful means -- can surely be accomplished in some other way. I can't tell what way that is, as I can't tell why you wanted to do this from your question. Maybe you'd benefit from reading over discriminated unions or typeclasses in the language reference.
As far as I understand this question. You want some Prolog-like behavior. I.e without typed predicates. In statically typed system you always can achieve such behavior by handling that by yourself. A lot of time ago I saw such example in Turbo Prolog (they implemented ISO prolog in terms of Turbo/Visual Prolog).
Consider something like (I'm not sure it is correct):
:- type any_type ---> atom_value(string)
; number_value(int)
; struct_value(any_type, list(any_type)).
guess(atom_value("v1")).
guess(atom_value("a")).
guess(atom_value("aa")).
guess(number_value(42)).
guess(struct_value(atom_value("pair"), [number_value(3), number_value(4)])).

Resources