Functional programming 如何将函数应用于变量?

Functional programming 如何将函数应用于变量?,functional-programming,ocaml,Functional Programming,Ocaml,让此类型= type intC = int;; type boolC = bool; type stringC = string;; type component = A of intC | B of boolC | C of stringC;; 如果我想在组件a的类型a上应用函数,我是否需要系统地解构该组件 例如,我必须做什么: let add comp = match comp with | A i -> Some (i + 2) (*only A interests

让此类型=

type intC = int;;
type boolC = bool;
type stringC = string;;

type component = A of intC | B of boolC | C of stringC;;
如果我想在组件a的类型a上应用函数,我是否需要系统地解构该组件

例如,我必须做什么:

let add comp =
  match comp with 
   | A i -> Some (i + 2) (*only A interests me, I return i + 2*)
   | _ -> None           (*otherwise I return nothing*)

那么对于组件a上的任何函数?有没有办法避免冗余?

您可以将一个高阶函数传递给一个为您销毁组件的函数

let apply_if_a f = function
   | A i          -> Some (f i)
   | (B _ | C _)  -> None
这种类型是

val apply_if_a : (int -> 'a) -> component -> 'a option

如您所见,对于应用于
A
的任何值的任何函数,都是多态的。此外,大多数人都远离“包罗万象”的概念,而是要做到穷尽。

这实际上取决于您将对类型执行哪种操作

@nlucaroni给出的解决方案非常好,但如果您想做一些更通用(和更复杂)的事情,可以使用记录保存部分映射函数:

type 'a component_m = {
  a : intC  -> 'a;
  b : boolC -> 'a;
  c : stringC -> 'a;
}

let map_component m = function
  | A a -> m.a a
  | B b -> m.b b
  | C c -> m.c c

let add = map_component {
  a = (fun x -> Some (x + 2)); 
  b = (fun _ -> None);
  c = (fun _ -> None);
}
如果不想每次都编写
(fun\ux->None)
函数,还可以使用扩展的默认值:

let none = {
  a = (fun _ -> None);
  b = (fun _ -> None);
  c = (fun _ -> None);
}

let add = map_component { none with a = fun x -> Some (x+2) }

你可以用函子做同样的事情,但在我看来这太过分了。

我明白了;这是处理这个问题的标准方法吗?是否有可能使它更通用于模块?这取决于数据代表什么。我从来没有做过这样的事情,并且会破坏所有的元素,但是我也不会太频繁地解构,并且会为
B
C
提供合适的案例。