5

让这个类型=

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 上的任何功能?有什么办法可以避免你的冗余?

4

2 回答 2

4

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

@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 _ -> None)每次都编写函数,还可以使用扩展的默认值:

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

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

你可以用仿函数做同样的事情,但在我看来,这变得有点矫枉过正了。

于 2012-04-26T18:53:25.733 回答
3

您可以将高阶函数传递给为您进行组件销毁的函数,

let apply_if_a f = function
   | A i          -> Some (f i)
   | (B _ | C _)  -> None

这个类型是,

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

如您所见,任何函数的多态都应用于A. 此外,大多数人都远离包罗万象的 ,_,而是详尽无遗。

于 2012-04-26T17:46:50.333 回答