Trying to understand indexed types - fstar

I'm trying to understand the vector type from the FStar tutorial:
type vector (a: Type) : nat -> Type =
| Nil : vector a 0
| Cons : hd: a -> n: nat -> tl: vector a n -> vector a (n + 1)
Constructing a vector - similarly to constructing ordinary lists - by Cons nat 3 Nil fails, while Cons nat 3 is accepted. Could someone explain to me where I'm wrong by reading Cons as requiring a tail parameter? Furthermore, how vectors with actual elements are created - or is it an "empty vector" type?

There is quite a bit of confusion here, sorry :)
The type argument a of vector is (for reasons that are also unclear to me) implicit for Nil and Cons. So when you write Cons nat the nat argument is really the hd argument and F* infers a to be Type0 (the type of nat). So you're constructing a vector of types, which might not be what you intended.
The reason Cons nat 3 Nil fails is because the 3 argument is wrong and doesn't correspond to the length of the Nil list. Cons nat 0 Nil works and is the vector of size 1 containing the single type nat.
The reason Cons nat 3 works is because you didn't yet give it the tl argument, so this is a partially applied constructor, Cons applied to 2 of its 3 arguments. The type of Cons nat 3 is vector Type0 3 -> vector Type0 4, so a function that expects a vector of size 3 in order to produce a vector of type 4.
Hope this helps.

Related

Compare a null list with [(a,b)] Haskell

I am a bit confused on how the lists in Haskell works.
I know that [] is an empty list with type [a].Is there a way to define an empty list with type [(a,b)]?
For example I know that null [1] == [] will give us True
null [(1,2)] == [] gave me the mismatched type error that's what I am assuming.
I want to know if it is possible to say something like null [(1,2)] == [(,)] will give us True
I know that [] is an empty list with type [a]
Yes, but it's important to understand what “type [a]” actually means. Really it means type forall a . [a], i.e. this is not a list of elements of some particular type “a” but rather, given any choice of type a, it is a list of that type. In particular, it can also be a list of tuple type. Thus, null works just as fine with lists of tuples as with lists of any other type.
To actually see null in action on such a tuple list, you just need to supply one. For instance, null [(1,2)] uses it for a tuple-list. But in case of the empty list, there's no content of the list with which you would constrain the type. It may either be clear from the context, as in
Prelude> [null l | l <- [ [], [(1,2)], [(1,3)] ]]
[True,False,False]
or you may explicitly specify it with a signature
Prelude> null ([] :: [(String, Double)])
True
Is there a way to define an empty list with type [(a,b)]?
Simply []. Indeed [] is an empty list, but the type of elements is free. It has type [a], but a can be the same as (b, c) so a 2-tuple with two different types.
For example I know that null [1] == [] will give us True
null :: Foldable f => f a -> Bool is a function that takes an f a (in this case an [a]), and returns a Bool. It checks if a list is empty. It does not generate a list.
i would declare my list like below :
let myList = [] :: [(Integer, Integer)]
then myList will have the type :t myList will yield myList :: [(Integer, Integer)]
When evaluating null myList it yields True
Every type of list is represented as []. If you want to specify the type you can use a signature ([] :: [(a, b)]), but often the compiler can infer the type from context:
λ> [] == [(1, 'x')]
False

Why is Haskell [] (list) not a type class?

I am writing a Haskell function which takes a list as input. That is, there's no reason it couldn't be a queue or dequeue, or anything that allows me to access its "head" and its "tail" (and check if it's empty). So the [a] input type seems too specific. But AFAIK there's no standard library typeclass that captures exactly this interface. Sure, I could wrap my function in a Data.Foldable.toList and make it polymorphic wrt Foldable, but that doesn't quite seem right (idiomatic).
Why is there no standard list type class? (And why is the "container" type class hierarchy in Haskell less developed than I think it should be?) Or am I missing something essential?
A given algebraic datatype can be represented as its catamorphism, a transformation known as Church encoding. That means lists are isomorphic to their foldr:
type List a = forall b. (a -> b -> b) -> b -> b
fromList :: [a] -> List a
fromList xs = \f z -> foldr f z xs
toList :: List a -> [a]
toList l = l (:) []
But foldr also characterises Foldable. You can define foldMap in terms of foldr, and vice versa.
foldMap f = foldr (mappend . f) mempty
foldr f z t = appEndo (foldMap (Endo . f) t) z
(It shouldn't be surprising that foldMap :: Monoid m => (a -> m) -> [a] -> m characterises lists, because lists are a free monoid.) In other words, Foldable basically gives you toList as a class. Instances of Foldable have a "path" through them which can be walked to give you a list; Foldable types have at least as much structure as lists.
Regarding your misgivings:
It's not like Foldable has functions head/tail/isEmpty, which is what I would find more intuitive.
null :: Foldable t => t a -> Bool is your isEmpty, and you can define (a safe version of) head straightforwardly with an appropriate choice of Monoid:
head :: Foldable t :: t a -> Maybe a
head = getFirst . foldMap (First . Just)
tail is kinda tricky in my opinion. It's not obvious what tail would even mean for an arbitrary type. You can certainly write tail :: Foldable t => t a -> Maybe [a] (by toListing and then unconsing), but I think any type T for which tail :: T a -> Maybe (T a) is defined would necessarily be structurally similar to lists (eg Seq). Besides, in my experience, the vast majority of cases where you'd think you need access to a list's tail turn out to be folds after all.
That said, abstracting over unconsable types is occasionally useful. megaparsec, for example, defines a Stream class for (monomorphic) streams of tokens to be used as input for a parser.
The Question
Making your question more concrete, let's ask:
Why isn't the type class
class HasHeadAndTail t where
head :: t a -> Maybe a
tail :: t a -> Maybe (t a)
isEmpty :: t a -> Bool
in the base library?
An Answer
This class is only useful for ordered, linear containers. Map, Set, HashMap, HashTable, and Tree all would not be instances. I'd even argue against making Seq and DList an instance since there are really two possible "heads" of that structure.
Also what can we say about any type that is an instance of this class? I think the only property is if isEmpty is False then head and tail should be non-Nothing. As a result, isEmpty shouldn't even be in the class and instead be a function isEmpty :: HashHeadAndTail t => t a -> Bool ; isEmpty = isNothing . head.
So my answer is:
This class lacks utility in so far as it lacks instances.
This class lacks useful properties and classes that lack properties are frequently discouraged.

What's the difference between these two functions?

I have two functions:
let rev_flatten l =
List.fold_left (fun acc x -> List.fold_left (fun acc y -> y::acc) acc x) [] l
The type is val rev_flatten : 'a list list -> 'a list = <fun>
and
let rev_flatten =
List.fold_left (fun acc x -> List.fold_left (fun acc y -> y::acc) acc x) []
The type is val rev_flatten : '_a list list -> '_a list = <fun>
I think it is the same functions, at least the same functionality, but why they have two different types? Why the second has the element type of _a? What is it?
A type variable with underscore as a prefix tells us that the variable is weakly polymorphic. A weakly polymorphic variable can be used only with one type, however a compiler can't deduce the exact type, so the type variable is mark with underscore.
When you provide an argument for the first time, a variable will no longer be polymorphic and will be able to accept arguments of a single type only.
Usually, a function is not generalized, but marked as weakly polymorphic if it might contain mutable state. In your example this is probably the case, because type system doesn't know if List.fold_left is pure or impure function.
Edit:
Why avoiding partial application (eta expansion) allows function (even impure) to be polymorphic?
Let's define a function that have an internal counter that is incremented and printed out every time the function is called. Among this, it takes a function as the argument and applies it after increasing the counter:
let count f =
let inc = ref 0 in
(fun x -> inc := !inc + 1; print_int !inc; f x);;
This function is polymorphic: ('a -> 'b) -> 'a -> 'b.
Next, let's define two more functions. A weekly polymorphic:
let max' = count max;;
val max' : '_a -> '_a -> '_a = <fun>
and a polymorphic one:
let max'' x = count max x;;
val max'' : 'a -> 'a -> 'a = <fun>
Now notice what is printed when we execute these functions:
max' 1 2;; (* prints 1 *)
max' 1 2;; (* prints 2 *)
max' 1 2;; (* prints 3 *)
max'' 1 2;; (* prints 1 *)
max'' 1 2;; (* prints 1 *)
max'' 1 2;; (* prints 1 *)
So the function that we designed as weekly polymorphic has a persistent mutable state inside that allows to use the counter as expected, while the polymorphic function is stateless and is reconstructed with every call, although we wanted to have a mutable variable inside.
This is the reason for a compiler to prefer a weakly polymorphic function that can be used with any single type instead of supporting full-fledged polymorphism.
A function with the type '_a list list -> '_a list is weakly polymorphic. What this means is that if you call the second one on an int list list, rev_flatten will no longer by '_a list list -> 'a list but int list list -> int list
You can read more here about the details of why here:
http://caml.inria.fr/resources/doc/faq/core.en.html
Cheers,
Scott
This is just the ML-style value restriction. There are some good references in a previous SO answer by gasche: What is the difference between 'a and '_l?.
Generally speaking the ML family applies a simple syntactic test to see whether it's safe to fully generalize, that is, to make a type fully polymorphic. If you generalize a case that's not safe, the program has undefined behavior (it can crash or get the wrong answer). So you need to do it only when safe.
The syntactic rule is applied because it's (relatively) easy to remember. A more complex rule was tried for a while, but it caused more harm than good (was the general conclusion). A historic description of the ML family will explain it better than I can.
One of your functions (the second one) is defined as an expression, i.e., as a function application. This is not "safe" according to the value restriction. (Remember, it's a syntactic test only.) The first is a lambda (fun x -> expr). This is "safe".
It's called the value restriction because it considers values to be safe. A function application is not a (syntactic) value. A lambda is a syntactic value. Something like [] is a value. Something like ref [] is not a value.

How to write the list in OCaml?

If I want to write list.ml in OCaml,
Q1
which way is correct?
type 'a list =
| Nil
| Cons of 'a * ('a list)
or
type 'a list =
| Nil
| Cons of 'a * 'a list
Any differences?
Q2
Also, how do I define the Cons inside the type definition as ::?
Q3
How do I define Nil inside the type definition as []?
Q1 -
There is no difference; each has two parameters associated to Cons. Although, Cons of ('a * 'a list) is different since it has one parameter, a tuple. You will come across that as an important distinction if you construct a tuple and try to wrap it in Cons as in, let x = a,Nil in Cons x. The choice depends on how you plan on constructing elements or some semantics of the data. In this particular case, no parenthesis should be used.
Q2 -
You cannot use : as the first character of infix function names as it is a keyword in the language -- :: is also a keyword regardless. In general infix operators can be defined with parenthesis around the function name and there is a special set of symbols allowed,
let (!!) a b = Cons( a,b )
Q3 -
This would require naming an identifier [], as in let [] = Nil. Those characters are not allowed in the naming conventions (see same link as above) as they are also individually keywords.

What is [] (list constructor) in Haskell?

I'm Having problems understanding functors, specifically what a concrete type is in LYAH. I believe this is because I don't understand what [] really is.
fmap :: (a -> b) -> f a -> f b
Is [], a type-constructor? Or, is it a value constructor?
What does it mean to have the type of: [] :: [a]?
Is it like Maybe type-constructor, or Just value constructor?
If it is like Just then how come Just has a signature like Just :: a -> Maybe a rather than Just :: Maybe a, in other words why isn't [] typed [] :: a -> [a]
LYAH says this as it applies to functors: Notice how we didn't write instance Functor [a] where, because from fmap :: (a -> b) -> f a -> f b, we see that the f has to be a type constructor that takes one type. [a] is already a concrete type (of a list with any type inside it), while [] is a type constructor that takes one type and can produce types such as [Int], [String] or even [[String]]. I'm confused though the type of [] implies it is like a literal for [a] what is LYAH trying to get at?
The type is described (in a GHCI session) as:
$ ghci
Prelude> :info []
data [] a = [] | a : [a] -- Defined
We may also think about it as though it were defined as:
data List a = Nil
| Cons a (List a)
or
data List a = EmptyList
| ListElement a (List a)
Type Constructor
[a] is a polymorphic data type, which may also be written [] a as above. This may be thought about as though it were List a
In this case, [] is a type constructor taking one type argument a and returning the type [] a, which is also permitted to be written as [a].
One may write the type of a function like:
sum :: (Num a) => [a] -> a
Data Constructor
[] is a data constructor which essentially means "empty list." This data constructor takes no value arguments.
There is another data constructor, :, which prepends an element to the front of another list. The signature for this data constructor is a : [a] - it takes an element and another list of elements and returns a resultant list of elements.
The [] notation may also be used as shorthand for constructing a list. Normally we would construct a list as:
myNums = 3 : 2 : 4 : 7 : 12 : 8 : []
which is interpreted as
myNums = 3 : (2 : (4 : (7 : (12 : (8 : [])))))
but Haskell permits us also to use the shorthand
myNums = [ 3, 2, 4, 7, 12, 8 ]
as an equivalent in meaning, but slightly nicer in appearance, notation.
Ambiguous Case
There is an ambiguous case that is commonly seen: [a]. Depending on the context, this notation can mean either "a list of a's" or "a list with exactly one element, namely a." The first meaning is the intended meaning when [a] appears within a type, while the second meaning is the intended meaning when [a] appears within a value.
It's (confusingly, I'll grant you) syntactically overloaded to be both a type constructor and a value constructor.
It means that (the value constructor) [] has the type that, for all types a, it is a list of a (which is written [a]). This is because there is an empty list at every type.
The value constructor [] isn't typed a -> [a] because the empty list has no elements, and therefore it doesn't need an a to make an empty list of a's. Compare to Nothing :: Maybe a instead.
LYAH is talking about the type constructor [] with kind * -> *, as opposed to the value constructor [] with type [a].
it is a type constructor (e.g. [Int] is a type), and a data constructor ([2] is a list structure).
The empty list is a list holding any type
[a] is like Maybe a, [2] is like Just 2.
[] is a zero-ary function (a constant) so it doesn't have function type.
Just to make things more explicit, this data type:
data List a = Cons a (List a)
| Nil
...has the same structure as the built-in list type, but without the (nicer, but potentially confusing) special syntax. Here's what some correspondences look like:
List = [], type constructors with kind * -> *
List a = [a], types with kind *
Nil = [], values with polymorphic types List a and [a] respectively
Cons = :, data constructors with types a -> List a -> List a and a -> [a] -> [a] respectively
Cons 5 Nil = [5] or 5:[], single element lists
f Nil = ... = f [] = ..., pattern matching empty lists
f (Cons x Nil) = ... = f [x] = ...`, pattern matching single-element lists
f (Cons x xs) = ... = f (x:xs) = ..., pattern matching non-empty lists
In fact, if you ask ghci about [], it tells you pretty much the same definition:
> :i []
data [] a = [] | a : [a] -- Defined in GHC.Types
But you can't write such a definition yourself because the list syntax and its "outfix" type constructor is a special case, defined in the language spec.