So i have a function that i'm trying to write:
fn (x:'a) => ???
(type: 'a -> int)
I've tried doing this:
fn (x:'a) => (x:int)
But obviously that returns a match constraint error. So is there any way I could go about doing this?
=== EDIT ===
Is there any way of 'reversing' the function? By this i mean having a function of type:
int -> 'a
Related
Say I have the following type and function:
exception NotFound
type 'a mytype = (string * 'a) list
fun foo [] = raise NotFound
| foo (x, b) :: bs = b
If I were to call the function and pass in an empty list, it will raise an Exception. Normally the function would return b, which is of type 'a. I want to handle the exception but I don't know what type 'a is, so what do I do here?
Related, but I really just want to return a bool. How do I do so?
Obviously the following code does not work as desired but it illustrates what I am trying to accomplish.
fun test mytypeobj = foo mytypeobj handle NotFound => false
(* return true otherwise *)
Your code contains a syntax error because of a left-parenthesis that comes a little too soon:
exception NotFound
type 'a mytype = (string * 'a) list
fun foo [] = raise NotFound
| foo (x, b :: bs) = b
I want to handle the exception but I don't know what type 'a is, so what do I do here?
The exception is unrelated to 'a, so handling it is a matter of:
val bar = foo [] handle NotFound => ...
I really just want to return a bool. How do I do so?
fun test mytypeobj = foo mytypeobj handle NotFound => false (* otherwise true *)
Since the function foo demonstrates no practical purpose, I am unsure what boolean you want to return. If you don't care if the boolean you're returning is the result of computing foo ..., you can do the following to discard the result and return a boolean of your choice:
fun test bs = (foo bs; true) handle NotFound => false
If b::bs is a list of booleans and you want to return the first of those, then that's what your function does. You can't be sure, of course, that it's true. The pattern I just mentioned is useful for unit testing when a function is throwing the right message. You could for example test that hd on the empty list correctly throws Empty:
fun test_hd_empty = (hd []; false) handle Empty => true
| _ => false
This test says that if hd [] doesn't throw, its result is discarded and the test fails. And if it does throw, but the exception isn't Empty, it should also fail.
I'm trying to make a typed version of React as an exercise in Ocaml.
To make it more functional, I'm passing a record as argument to render.
type ('props,'state) reactInstance =
{
props: 'props;
state: 'state;
updater: 'a . ('props,'state) reactInstance -> 'a -> 'state -> unit;}
and ('props,'state) reactClass =
{
getInitialState: unit -> 'state;
render: ('props,'state) reactInstance -> element;}
module type ComponentBluePrint =
sig
type props
type state
val getInitialState : unit -> state
val render : (props,state) reactInstance -> element
end
module type ReactClass =
sig
type props
type state
val mkUpdater :
props ->
((props,state) reactInstance -> 'e -> state) ->
(props,state) reactInstance -> 'e -> unit
val reactClass : (props,state) reactClass
end
module CreateComponent(M:ComponentBluePrint) =
(struct
include M
let rec mkUpdater props f i e =
let nextState = f i e in
let newInstance =
{ props; state = nextState; updater = (mkUpdater props) } in
()
let reactClass =
{ render = M.render; getInitialState = M.getInitialState }
end : (ReactClass with type props = M.props and type state = M.state))
One thing I don't understand is why the compiler can't infer the type of updater = (mkUpdater props) in let newInstance = { props; state = nextState; updater = (mkUpdater props) }.
Error: Signature mismatch:
Values do not match:
let mkUpdater :
props =>
(reactInstance props state => '_a => '_b) =>
reactInstance props state => '_a => unit
is not included in
let mkUpdater :
props =>
(reactInstance props state => 'e => state) =>
reactInstance props state => 'e => unit
What's the difference between '_a and 'e ?
It looks exactly to same to me. How do I make this type check?
A type variable '_a (the actual letter doesn't matter, the crucial thing is the underscore) is a so called weak type variable. This is a variable that cannot be generalized, i.e., it can be substituted with only one concrete type. It is like a mutable value, but in the realm of types.
A type denoted with a weak type variable '_a is not included in a type that is denoted with a generic type variable. Moreover, it even can't escape the compilation unit, and should be either hidden or concretized.
Weak type variables are created when an expression is not a pure value (that is defined syntactically). Usually, it is either a function application, or an abstraction. It is usually possible, to get rid of weak type variables by doing a so called eta-expansion, when you substitute a partially applied function to a normal function application by enumerating all function arguments, i.e., updater = (fun props f i e -> mkUpdater props f i e).
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'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.