有没有办法减少这里的重复?

问题描述

我正在创建一个囚徒困境模拟,我有两个函数计算两个玩家的合作和背叛,并将它们作为一个元组输出。我看到了很多相似之处,并希望获得一些有关如何将这两个函数合并为两个函数可以调用的另一个函数的指导,这样我就不会重用代码。我是 OCaml 的新手,所以我正在努力寻找一种方法来做到这一点!

以下是必要的信息:

type action = bool ;;
type play = action * action ;;
type history = play list 

let rec count_defections (history : history) : (int * int) = 
  match history with
  | [] -> (0,0)
  | play :: rest ->
    match play with
    | (player1,player2) ->
      match count_defections rest with
      | (d1,d2) ->
        if (player1,player2) = (false,false) then (d1 + 1,d2 + 1)
        else if (player1,true) then (d1 + 1,d2)
        else if (player1,player2) = (true,false) then (d1,d2 + 1)
        else (d1,d2) ;;

let rec count_cooperations (history : history) : (int * int) = 
  match history with
  | [] -> (0,player2) ->
      match count_cooperations rest with
      | (d1,true) then (d1,d2) ;;

我的第一个想法是:

let count_common (history : history) : (int * int) =
  match history with
  | [] -> (0,player2) ->
      match .....

但我真的不明白剩下的怎么办。

解决方法

这是一个函数,它分别计算一对的两个部分,计算等于给定值的元素。

let count_val_in_pairs value pairs =
    List.fold_left
        (fun (cta,ctb) (a,b) ->
            ((if a = value then cta + 1 else cta),(if b = value then ctb + 1 else ctb)))
        (0,0)
        pairs

您的 count_defections 是这样的:

let count_defections history =
    count_val_in_pairs false history

您的 count_cooperations 是这样的:

let count_cooperations history =
    count_val_in_pairs true history