I’m trying to add a new semantic check and can’t figure out how to turn a list of Validate.ok | Validate.error’s into a single Validate error. I have the following code:
match function_block_stmts_opt with
| Some  | None -> ok ()
| Some ls ->
List.map ~f:check_fun_def_body_in_block ls |> sequence
where check_fun_def_body_in_block returns a Validate.ok or error as well. I’m getting this type error:
Error: This expression has type unit list t
but an expression was expected of type unit t
Type unit list is not compatible with type unit
on the map and sequence call. I seem to remember you explicitly saying using the Validation applicative (not monad!) helps you deal with this case, but I can’t figure out how to use it. Help appreciated!
The type of
'a t list -> 'a list t (where
You are applying
check_fun_def_body_in_block : ('a,'b) stmt list option -> unit t to each element of the list giving you a
unit t list. When you then sequence the effects, you get back
unit list t.
However, in the first case of your match statement, you are returning
unit t. Since
unit t does not equal
unit list t (!) it will not type check.
There are two ways to fix this:
ok  from the first branch and add
Validation.map ~f:List.concat after
sequence on the second branch;
Validation.map ~f:(fun _ -> ()) after
sequence on the second branch.
(EDIT: it turns out I can’t code without a type checker… you will still have to flatten the list of lists for the first option, above)
The semantic check code isn’t quite where I want it to be at the moment so it probably doesn’t matter which you use (
Semantic_check currently performs type checking which requires a monadic interface - see below) but I would usually prefer the first option. It might be worth taking a look at the docs I added explaining
apply works here.
If the computations are independent (i.e. checking the validity of one statement does not depend on the result of a previously checked statement) you only require the
Validation should not really support the
Monad interface since the implementation violates the monad laws and, more practically, doing so means it doesn’t actually accumulate errors through monadic bind!.
NB In the PR I submitted yesterday for semantic warnings I actually changed the interface to validation to match the standard
Core_kernel signatures so
sequence is called