functional-programmingocamlmonads# OCaml Addable Numbers

I'm learning OCaml, from a little bit of Haskell that I studied for my thesis, and I'm wondering if there is a similar mechanism (type classes) to expresses that two numbers are addable (like a generic for int, float, string, etc). I know that in OCaml type classes don't exist but I'm wondering for similar mechanism to express the same thing

I'm trying to make a module type that have the common "method" add, but without success.

```
module type Addable = sig
type t
val add : t -> t -> t
val zero : t
val one : t
end
module Addable_int : Addable with type t = int = struct
type t = int
let add a b = a + b
let zero = 0
let one = 1
end
module Addable_float : Addable with type t = float = struct
type t = float
let add a b = a +. b
let zero = 0.
let one = 1.
end
let rec sum (type a) (module A : Addable with type t = a) =
match l with
| [] -> A.zero
| x::l -> A.add x (sum (module A) l)
```

Update: The function sum give an error: "This expression has type 'a but an expression was expected of type a The type constructor a would escape its scope"

Update-Update:

```
module type NumberType = sig
type t
val add : t -> t -> t
val zero : t
val one : t
end
module IntNumber : NumberType with type t = int = struct
type t = int
let add x y = x + y
let zero = 0
let one = 1
end
module FloatNumber : NumberType with type t = float = struct
type t = float
let add x y = x +. y
let zero = 0.0
let one = 1.0
end
module Addbl (M: NumberType) = struct
type t = M.t
let add x y = M.add x y
let zero = M.zero
let one = M.one
end
let rec sum : type a. (module NumberType with type t = a) -> a list -> a =
fun (module M) l ->
match l with
| [] -> M.zero
| x::t -> M.add x (sum (module M) t)
let () =
let xs = [1.;2.;3.] in
let _ = print_float @@ sum (module FloatNumber) xs in
let _ = print_string "\n" in
let xsi = [1;2;3;4] in
print_int @@ sum (module IntNumber) xsi
```

This code work and the sum function is generalized. I don't know if there is a way to eliminate the need to pass (module IntNumber) or (module FloatNumber) in the sum function, to abstract this behaviour

Solution

No, OCaml does not have type classes.

But, consider the `Float`

and `Int`

modules both implement several common functions, like `add`

, `sub`

, `mul`

, `div`

, etc.

They also both have a type `t`

and implement these functions in terms of `t`

. This allows for a functor to abstract out these behaviors and work much the same way.

```
# module type NumberType = sig
type t
val add : t -> t -> t
val sub : t -> t -> t
val mul : t -> t -> t
val div : t -> t -> t
end
module Math (N : NumberType) = struct
type t = N.t
let ( + ) = N.add
let ( - ) = N.sub
let ( * ) = N.mul
let ( / ) = N.div
end;;
module type NumberType =
sig
type t
val add : t -> t -> t
val sub : t -> t -> t
val mul : t -> t -> t
val div : t -> t -> t
end
module Math :
functor (N : NumberType) ->
sig
type t = N.t
val ( + ) : t -> t -> t
val ( - ) : t -> t -> t
val ( * ) : t -> t -> t
val ( / ) : t -> t -> t
end
# let open Math (Int) in
45 + 67;;
- : int = 112
# let open Math (Float) in
45.6 + 87.2;;
- : float = 132.8
```

An example with an `Addable`

type using functors:

```
# module type Addable = sig
type t
val nil : t
val add : t -> t -> t
end;;
module type Addable =
sig type t val nil : t val add : t -> t -> t end
# module SumList (A : Addable) = struct
type t = A.t
let sum_list = List.fold_left A.add A.nil
end;;
module SumList :
functor (A : Addable) ->
sig type t = A.t val sum_list : t list -> t end
# let open SumList (struct include Int let nil = 0 end) in
sum_list [1; 2; 3; 4];;
- : int = 10
# let open SumList (struct
include String
let nil = ""
let add = (^)
end) in
sum_list ["foo"; "bar"; "baz"];;
- : string = "foobarbaz"
```

You might also use the same `Addable`

module signature with first class modules to avoid the need for the functors, allowing one function to sum lists of different types.

```
# let sum_list
(type a)
(module A : Addable with type t = a)
(lst : a list) =
List.fold_left A.add A.nil lst;;
val sum_list : (module Addable with type t = 'a) -> 'a list -> 'a = <fun>
# module IntAdd = struct
type t = int
let nil = 0
let add = (+)
end;;
module IntAdd : sig type t = int val nil : t val add : t -> t -> t end
# module StringAdd = struct
type t = string
let nil = ""
let add = (^)
end;;
module StringAdd : sig type t = string val nil : t val add : t -> t -> t end
# module FloatAdd = struct
type t = float
let nil = 0.
let add = (+.)
end;;
module FloatAdd : sig type t = float val nil : t val add : t -> t -> t end
# sum_list (module IntAdd) [1; 2; 3; 4; 5];;
- : int = 15
# sum_list (module StringAdd) ["1"; "2"; "3"; "4"; "5"];;
- : string = "12345"
# sum_list (module FloatAdd) [1.; 2.; 3.; 4.; 5.];;
- : float = 15.
```

- How is the Foldable instance of (,) useful?
- What is the proper way of wrapping an Int (not a general type) in another type if type safety is the only motive?
- Edit(Mutate) object property inside a reducer in NgRx
- When is it right time to throw an exception in functional programming
- Using apply for calculating subscale and total scores across multiple dataframes
- How to implement db capability approach with pure functions in F#?
- Find a pair of integers from an array that sums up to a given number in Java 8 using functionals
- How to join array of optional integers to string?
- Which functions in Array.prototype are pure function in Javascript
- Is this property of a functor stronger than a monad?
- How do I make a minimal working example for the a DBus server?
- unfamiliar syntax in Haskell / Clash function type signature
- How can I write a notification server in Haskell?
- How to debug with PureScript?
- Generic Map function in Golang
- Learning functional/Clojure programming - practical exercises?
- Python functional method of checking that all elements in a list are equal
- javascript fold reduce functional programming
- Typescript types for a pipe() function
- Can you explain closures (as they relate to Python)?
- Zipping streams using JDK8 with lambda (java.util.stream.Streams.zip)
- Unable to understand the strange "where" syntax in Haskell / Clash
- Codensity and ContT
- Python fluent filter, map, etc
- functional programming in python - using map(), filter(), and sum() together - java .stream() equivalent?
- Haskell foldr1 lambda function which adds tuple values
- How can I get the nested keys of a map in clojure?
- How do I use System.Console.ANSI to wrap a String in escape sequences for getting it colored in the terminal?
- Flux.switchIfEmpty - what if it doesn't switch when first Flux is completed?
- Does Raku has a data type for encoding side effects as pure values?