Question

I am trying to typecast a value from one type another.

type days =
  | Mon | Tue | Wed | Thu | Fri | Sat

type ('a, 'b) holidays = H of 'a | W of 'b
(* H: holiday, W: Working *)

let my_list = [H Mon; H Tue; W Wed]

From the above my_list, I would like to extract, "Mon" and not "H Mon". How can I go about it, without hardcoding a pattern matching such as

let result day = match day with
| H Mon -> Mon

etc?

That is I would like to extract the first element of my_list as if I never applied the parameterized construct H or W. Thank you...!

Was it helpful?

Solution

You don't need to allow the ('a, 'b) to be different types if they are always going to be type=days. As written, you can't have the return value of your 'result' function arbitrarily return either a 'a or 'b if they actually were different. The return type of the result function must be exactly 'a or 'b.

There's 100 ways you could go to resolve this. Here is one where you simply restrict the inner type of H and W to be the same thing:

type 'a holiday = |H of 'a |W of 'a

let head_of_holiday_list = fun holiday_list -> begin
   let first_day::xs = holiday_list in
   match first_day with
   |H(x) -> x
   |W(x) -> x
   end

Alternatively, you can separate the holiday and days completely, and formalize your list into something called a calendar which is made up of pairs of the two types. This is probably the cleaner way to decouple the two types:

type day_of_week = |Mon |Tues |Wed ..
type kind_of_day = |Holiday |Workday
type calendar = (day_of_week, kind_of_day) list

let first_day_of_week_in_calendar = fun calendar -> begin
  let (day_of_week_x, kind_of_day_y)::xs = calendar in
  day_of_week
  end

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top