I am learning Ocaml by building a parser. I need help with how I can express below type definition in Ocaml. I have given an example from Haskell code.
data DurSecond = DurSecond Integer deriving (Eq, Ord, Show)
data DurMinute = DurMinute Integer (Maybe DurSecond) deriving (Eq, Ord, Show)
data DurHour = DurHour Integer (Maybe DurMinute) deriving (Eq, Ord, Show)
data DurTime = DurTimeHour DurHour
| DurTimeMinute DurMinute
| DurTimeSecond DurSecond deriving (Eq, Ord, Show)
data DurDay = DurDay Integer deriving (Eq, Ord, Show)
data DurWeek = DurWeek Integer deriving (Eq, Ord, Show)
data DurMonth = DurMonth Integer (Maybe DurDay) deriving (Eq, Ord, Show)
data DurYear = DurYear Integer (Maybe DurMonth) deriving (Eq, Ord, Show)
data DurDate = DurDateDay DurDay (Maybe DurTime)
| DurDateMonth DurMonth (Maybe DurTime)
| DurDateYear DurYear (Maybe DurTime) deriving (Eq, Ord, Show)
data Duration = DurationDate DurDate
| DurationTime DurTime
| DurationWeek DurWeek deriving (Eq, Ord, Show)
Leaving aside the deriving of instances which can be done with ppx_deriving, let me focus on the types themselves. In OCaml a lot of these types can be automatically derived from the same base type using the technique shown here: http://dev.realworldocaml.org/files-modules-and-programs.html#nested-modules
So e.g.
module type DURATION = sig
type t
val of_int : int -> t
val to_int : t -> int
end
module Duration = struct
type t = int
let of_int = Fun.id
let to_int = Fun.id
end
module Second : DURATION = Duration
module Day : DURATION = Duration
module Week : DURATION = Duration
type minute = int * Second.t option
type hour = int * minute option
type time = Hour of hour | Minute of minute | Second of Second.t
type month = int * Day.t option
type year = int * month option
type date =
| Day of Day.t * time option
| Month of month * time option
| Year of year * time option
type duration = Date of date | Time of time | Week of Week.t
A couple more notes about this approach:
- The types that are purely ints get their own wrapper modules
- Other types are defined as just pairs but they can be created unambiguously because their second elements expand out to the wrapped types
-
time
, date
, and duration
are variants like in the Haskell code
1 Like