I am trying to write a declaration of two mutually inductive datatypes that both take a type parameter as arguments as follows:
noeq
type foo 'a =
| FooA: x: 'a -> foo 'a
| Foob: y: bar 'a -> foo 'a
and bar 'b =
| BarA: x: int -> bar 'b
| BarF: y: foo 'b -> bar 'b
I get an error message that is as follows:
LabeledStates.fst(59,0-64,31): (Error 67) Failed to solve universe inequalities for inductives
1 error was reported (see above)
(where line 59 is the line that includes "type foo 'a")
What does this error mean and what can I do to fix it?
If I remove the type parameters (and give foo.x the type of int, for example) I do not get errors anymore. Similarly, if I just give one of the types a type parameter but not the other, I also do not have errors.
F* isn't capable of inferring universes in cases like this. You can provide explicit universe instantiations, however. For example, here are three possible solutions:
First, a doubly universe polymorphic one, most general but also possibly quite cumbersome to use
noeq
type foo (a:Type u#a) : Type u#(max a b) =
| FooA: x: a -> foo a
| Foob: y: bar u#b u#a a -> foo a
and bar (b:Type u#b) : Type u#(max a b) =
| BarA: x: int -> bar b
| BarF: y: foo u#b u#a b -> bar b
A singly universe polymorphic solution, perhaps a bit simpler, though less general:
noeq
type foo1 (a:Type u#a) : Type u#a =
| Foo1A: x: a -> foo1 a
| Foo1b: y: bar1 u#a a -> foo1 a
and bar1 (b:Type u#a) : Type u#a =
| Bar1A: x: int -> bar1 b
| Bar1F: y: foo1 u#a b -> bar1 b
And, finally, a version specialized to universe 0, probably the easiest to use if it fits your needs, but also least general:
noeq
type foo0 (a:Type u#0) : Type u#0 =
| Foo0A: x: a -> foo0 a
| Foo0b: y: bar0 a -> foo0 a
and bar0 (b:Type u#0) : Type u#0 =
| Bar0A: x: int -> bar0 b
| Bar0F: y: foo0 b -> bar0 b
Related
I'm trying to use the module type Partial_information which is constructed via the functor Make_partial_information as the type of the field contents in the type Cell.t. However, I'm getting the error Unbound module Partial_information.
open Core
(* module which is used as argument to functor *)
module type Partial_type = sig
type t
val merge : old:t -> new_:t -> t
end
(* type of result from functor *)
module type Partial_information = sig
type a
type t = a option
val merge : old:t -> new_:t -> t
val is_nothing : t -> bool
end
(* The functor *)
module Make_partial_information(Wrapping : Partial_type):
(Partial_information with type a = Wrapping.t)
= struct
type a = Wrapping.t
type t = a option
let merge ~(old : t) ~(new_ : t) =
match (old, new_) with
| (None, None) -> None
| (None, Some a) -> Some a
| (Some a, None) -> Some a
| (Some a, Some b) -> (Wrapping.merge ~old:a ~new_:b) |> Some
let is_nothing (it: t) : bool = (is_none it)
end
(* Checking to make sure understanding of functor is correct *)
module Int_partial_type = struct
type t = int
let merge ~old ~new_ = new_ [##warning "-27"]
end
module Int_partial_information = Make_partial_information(Int_partial_type)
(* Trying to use _any_ type which might have been created by the functor as a field in the record *)
module Cell = struct
type id = { name : string ; modifier : int }
type t = {
(* Error is here stating `Unbound module Partial_information` *)
contents : Partial_information.t ;
id : id
}
end
Module types are specifications for modules. They do not define types by themselves. They are also not constructed by functors in any way.
Consequently, it is hard to tell what you are trying to do.
As far I can see, you can simply define your cell type with a functor:
module Cell(P : Partial_information) = struct
type id = { name : string ; modifier : int }
type partial
type t = {
contents : P.t;
id : id
}
end
Or it might be even simpler to make the cell type polymorphic:
type 'a cell = {
contents : 'a;
id : id
}
since the type in itself is not particularly interesting nor really dependent upon
the type of contents.
P.S:
It is possible to use first class modules and GADTs to existentially quantify over a specific implementation of a module type. But it is unclear if it is worthwhile to explode your complexity budget here:
type 'a partial_information = (module Partial_information with type a = 'a)
module Cell = struct
type id = { name : string ; modifier : int }
type t = E: {
contents : 'a ;
partial_information_implementation: 'a partial_information;
id : id
} -> t
end
I don't have any idea wht I can't define a bin_tree like this :
type 'a bin_tree = Node of { data : 'a ; left : 'a bin_tree; right : 'a bin_tree; } | Leaf
Merlin tells me : error inside type, expecting _
You are using inline records, a new language feature that has only been available since version 4.03.0.
Since 4.03.0, it has been possible to do the following:
type t = A of { ... } | B
Before 4.03.0, you had to define the record type separately:
type t = A of r | B and r = { ... }
You have to either rewrite your code accordingly or switch your OCaml installation to version 4.03.0 or later.
The record type is not defined yet - and the record definition is related to bin_tree and so you have to define them jointly, try :
type 'a pp = {data : 'a; left: 'a bin_tree; right : 'a bin_tree} and
'a bin_tree = Node of 'a pp | Leaf ;;
In OCaml, it is possible to define explicit polymorphic type in a record
type foo = { f : 'a. unit -> 'a };;
It seems we can assign only general values to f like
{ f = fun () -> failwith ""; }
or
{ f = fun () -> exit 1; }
How to use this language feature in real world? Is there any good practical example?
This isn't really connected with records. If you declare any function to have type 'a. unit -> 'a (takes nothing and returns whatever the caller wanted) then you can only use it for functions that don't return.
Here's a slightly more useful example: a record containing a function for finding the length of lists (of any type).
# type foo = { f : 'a. 'a list -> int };;
type foo = { f : 'a. 'a list -> int; }
# let foo = { f = List.length };;
val foo : foo = {f = <fun>}
# foo.f [1;2;3];;
- : int = 3
It can be useful if you wanted to pass a function like List.length as an argument to another function, and have it use it on multiple types:
Say we want to pass List.length to test. We can't do it directly:
# let test fn = fn [1;2;3] + fn ["a";"b";"c"];;
Error: This expression has type string but an expression was expected of type
int
But we can use a record:
# let test foo = foo.f [1;2;3] + foo.f ["a";"b";"c"];;
val test : foo -> int = <fun>
# test foo;;
- : int = 6
Let two variant types :
type typeA =
| A1
| A2
;;
type typeB =
| B1 of typeA
| B2 of typeA
;;
and type-checking functions :
let isA1 = function A1 -> true | _ -> false;;
let isA2 = function A2 -> true | _ -> false;;
let isB1 = function B1 e -> true | _ -> false;;
let isB2 = function B2 e -> true | _ -> false;;
I'd like to create a list of those functions to check elements of type A or B
as they're of different types, I need polymorphic variants and I get :
type filterA =
{
handleA : typeA -> bool;
};;
type filterB =
{
handleB : typeB -> bool;
};;
type filterslist = [`FilterA of filterA | `FilterB of filterB] list ;;
let filters1 = [`FilterA { handleA = isA1 }; `FilterB { handleB = isB1 }] ;;
So now I want to iterate over filters1 to check the type of the argument
I tried :
let exec_filters filters event = List.iter (fun fil -> match fil with `FilterA -> fil.handleA event; ()| `FilterB -> fil.handleB event; () ) filters;;
but it's not appreciated :
Error: This expression has type [< `FilterA | `FilterB ]
but an expression was expected of type filterA
How can I handle this ?
The fact that you're using "type checking predicates" similar to Scheme or instanceOf indicates that there is probably something very wrong with your code. OCaml is a statically typed language, you should not:
iterate over filters1 to check the type of the argument I tried
Why are you doing this? If you are trying to handle multiple types, the way to do it is to use polymorphism. Polymorphic variants can be helpful for this, but I'm still not convinced that your code isn't just written in a strange way.
I think your code should read like:
let exec_filters filters event =
List.iter
(fun fil -> match fil with
| `FilterA fA -> fA.handleA event; ()
| `FilterB fB -> fB.handleB event; () )
filters;;
EDIT: However, this won't typecheck, since event can't have types typeA and typeB...
Why not make your initial variants (typeA and typeB) polymorphic?
What are you trying to do?
When you say
match fil with
`FilterA -> ...
You seem to expect that this will change the type of fil, but that's not how it works. The expression with the type filterA appears inside the pattern. You want something more like this:
match fil with
`FilterA { handleA = h } -> h event
I'm not sure I see the purpose of having your handlers return bool if you're going to use List.iter to execute them. This will return unit, and the bool values are going to be discarded.
Edit
There's a deeper typing problem, explained well by Ptival. So even if you fix your patterns you'll still need to rethink your plan. One possible thing to do would be to use variants (not necessarily polymorphic variants, by the way) to track the types of the events.
I need to have two classes refering to each other. Is there any way in Ocaml to make Forward Declaration of one of them?
(I don't think it's possible as with easier stuff with word and).
Or maybe it is possible, but different way than how i tried?
Ocaml doesn't have anything like forward declarations (i.e. a promise that something will be defined eventually), but it has recursive definitions (i.e. a block of things that are declared and then immediately defined in terms of each other). Recursive definitions are possible between expressions, types, classes, and modules (and more); mutually recursive modules allow mixed sets of objects to be defined recursively.
You can solve your problem using a recursive definition with the keyword and:
class foo(x : bar) = object
method f () = x#h ()
method g () = 0
end
and bar(x : foo) = object
method h () = x#g()
end
Or you could use parameterized classes. Following the previous example you have:
class ['bar] foo (x : 'bar) =
object
method f () = x#h ()
method g () = 0
end
class ['foo] bar (x : 'foo) =
object
method h () = x#g()
end
The inferred interface is:
class ['a] foo : 'a ->
object
constraint 'a = < h : unit -> 'b; .. >
method f : unit -> 'b
method g : unit -> int
end
class ['a] bar : 'a ->
object
constraint 'a = < g : unit -> 'b; .. >
method h : unit -> 'b
end