I'd like to apply a functions stored in a list
let functions = [(fun () -> print_string "fun 1"); (fun () -> print_string "fun 2")]
with a high-order function like List.iter, to display "fun 1" and "fun 2"
Is there a way to do that ?
Here is the way to do it:
List.iter (fun f -> f()) functions
Your list consists of functions with the signature unit -> unit. Therefore, if you supply () as a parameter for each function, they will return unit which is obvious to use inside List.iter.
Related
I had this idea of a type-safe templating language that would use polymorphic variants as a source of type-safe variables that can be substituted for text, for example:
type 'a t = Var of 'a | Text of string | Join of 'a t * 'a t
let rec render ~vars = function
| Text source -> source
| Var label -> vars label
| Join (left, right) -> render left ~vars ^ render right ~vars
let result = render (Join (Var `Foo, Text "bar")) ~vars:(function `Foo -> "foo");;
let () = assert (result = "foobar")
This is all fine: compiler will enforce that you don't forget a substitution variable, or that you don't have a typo in a variable name—thanks to polymorphic variants.
However, I find two problems:
You can accidentally supply an unused variable.
If template contains no variables, you are still forced to supply a ~vars function, and the only one that would work would be fun _ -> "" or fun _ -> assert false, which compromizes type-safety in case the template ever changes.
I'm looking for advice on the problems above, but I also appreciate any applicable advice on API design.
Nothing force you to always use polymorphic variants. you could have a void type that is guaranteed to be different to every polymorphic variant.
type void
let empty_vars : void -> string = fun _ assert false
When you apply it to an empty template, you end up with
let result = render (Text "bar") ~vars:empty_vars
That way, if you later add a variable to your template, you will immediately notice it through the type error.
For unused variables, the best I can suggest is also not to use polymorphic variants:
type v = Foo
let result = render (Join (Var Foo, Text "bar")) ~vars:(function Foo -> "foo");;
This will only catch unused cases in the function definition, but of course if you remove a part of your template, you won't notice anything.
One other solution that have similar properties but may, or may not suit your taste is to use objects.
let rec render ~vars = function
| Text source -> source
| Var label -> label vars
| Join (left, right) -> render left ~vars ^ render right ~vars
let foo v = v#foo
let result = render (Join (Var foo, Text "bar")) ~vars:object method foo = "foo" end
That way you can keep the same pattern when no variables are used:
let result = render (Text "bar") ~vars:object end
But still no unused variable check.
I think it is impossible with polymorphic variants. The type of render function is:
val render : var:('a -> string) -> 'a t -> string
and the partial application render (Join (Var `Foo, Text "var")) has the following type:
vars:([> `Foo ] -> string) -> string
What you want to do is to close the opened variant type [> `Foo ] and restrict it to [ `Foo ] -> string in order to exclude functions which can get larger inputs like [< `Foo | `Bar ] -> string.
The only way to restrict the type is to add a type constraint: (vars : [ `Foo ] -> string), listing all the tags you want explicitly, but this is what you want to avoid...
I want to know if we can have a local module inside the module. This can be achieved if a functor can be passed as an argument to another functor. But I am not sure if we can do that.
My apologies if this is a vague question.
Thanks.
Yes, it is possible to define higher-order functors. Here is a simple example of a functor that applies its first argument to its second argument:
module App (F : functor (X: sig end) -> sig end) (X: sig end) = F (X)
This is however unrelated to the question of having local modules, which are very straightforward and do not require functors. The following example defines a submodule B that remains private to A:
module A : (sig val g : unit -> unit end) = struct
module B = struct
let f () = print_endline "Hello"
end
let g = B.f
end
let () = A.g () (* valid, prints Hello *)
let () = A.B.f () (* invalid *)
If I define a function with tuple-style parameters, I can define the parameter types and the return types:
fun hello(name:String, code:int):String = "hello!"
But if I use curry-style, I can only do it like this:
fun hello name code = "hello!"
Is it possible to add parameter types or return types for the later one?
It is indeed possible:
fun hello (name : string) (code : int) : string = "hello!"
However, type-annotations are seldom needed or used in Standard ML, so it's most often preferred to omit them.
Another way to do this if the function isn't curried is to specify the full function type, a la Haskell,
val hello : string * int -> string =
fn (name, code) => "hello!"
You can do this with recursive functions too
val rec hello : string * int -> string =
fn (name, code) => hello ("hello!", 5)
Uncurried functions are a bit messier, though the type description is still nicer.
val hello : name -> int -> string =
fn name => fn code => "hello!"
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