规则类型不同意

发布于 2025-02-10 09:11:30 字数 4511 浏览 2 评论 0原文

我正在尝试在SML中编写一个程序以解决以下问题:

游戏的游戏列表和一个进球。玩家有一个持有卡的列表,最初是空的。玩家 通过两幅绘图进行移动,这意味着从卡片列表中删除卡片列表中的第一张卡, 将其添加到持有卡片或丢弃中,这意味着选择其中一张保存卡以删除。游戏 当玩家选择不再采取动作或持有卡的值之和时,要么结束 大于目标。写一个函数主持人,“运行游戏”。它获取卡列表(卡列表)一个移动列表 (玩家在每个点都“做”的事情)和一个INT(目标),并在结束时返回分数 在处理(某些或全部)移动列表中的移动后,游戏按顺序进行操作。使用本地定义的递归 辅助功能将几个参数共同代表游戏的当前状态。作为 上面描述:

  • 游戏开始于held-cards是空列表。
  • 如果没有更多动作,游戏结束。 (由于移动列表为空,因此玩家选择停止。)
  • 如果玩家丢弃了一些卡片,请继续使用“继续播放”(即进行递归电话) 没有C和卡列表不变。如果C不在持有的卡中,请提高非法人 例外。
  • 如果玩家绘制并且卡列表已经(已经)为空,则游戏结束了。否则绘画原因 超过目标的持有卡的总和已经结束(绘制后)。否则比赛仍在继续 带有较大的固定卡和较小的卡片列表。

这是我的解决方案:

datatype suit = Clubs | Diamonds | Hearts | Spades
datatype rank = Jack | Queen | King | Ace | Num of int 
type card = suit * rank

datatype move = Discard of card | Draw 

exception IllegalMove

fun remove_card (cs, c, e) =
    let
       fun delete_it (cs, c, e, count, acs) =
           case cs of
           [] => if count = 0 then raise e else acs
         | cp::cs' => if cp = c andalso count = 0
                      then delete_it (cs', c, e, count + 1, acs)
                      else
                          if cp = c then delete_it (cs', c, e, count + 1, [cp] @ acs) else delete_it (cs', c, e, count, [cp] @ acs)                
    in
       delete_it (cs, c, e, 0, [])
    end 

fun sum_cards (loc) =
    let
        fun sum_it (loc, sum) =
           case loc of
           [] => sum
         | c::loc' => sum_it (loc', sum + card_value (c))
    in
        sum_it (loc, 0)
    end 

fun score (loc, goal) =
    let
        val sum = sum_cards (loc)
        val all_same = all_same_color (loc)         
    in
        let
           fun prem_score (sum, goal) =
               if sum > goal
               then 3 * (sum - goal)
               else goal - sum     
        in
           let 
              val pre_score = prem_score (sum, goal)
              fun final_score (all, pre) =
                  if all
                  then pre div 2
                  else pre
        in
           final_score (all_same, pre_score)
        end         
    end
    end

fun officiate (loc, lom, goal) =
    let
    fun get_score (lcards, lohc, lmoves, goal, e) =
        case lmoves of
        [] => score (lcards, goal)
          | Draw::lmoves' => case lcards of
                   [] => score (lcards, goal)
                 | c::loc' => if sum_cards (c) > goal
                          then score (lcards, goal)
                          else get_score (loc', c::lohc, lmoves', goal, e)
          | d::lmoves' => case d of
                 Discard c => get_score (loc, remove_card (lohc, c, e), lmoves', goal, e)        
    in
    get_score (loc, [], lom, goal, IllegalMove)
    end                    

ihe函数sum_cards返回给定卡列表的值总和。 得分功能返回游戏的分数,而remove_card返回卡片列表减去所提供的卡。所有这些功能都可以完美地工作,但是问题在主持功能中,因为我试图使用另外两个助手功能,但没有运气。这是错误日志:

hw2.sml:196.17-196.60 Error: operator and operand don't agree [tycon mismatch]
  operator domain: (suit * rank) list * (suit * rank) list list * 'Z * int * 
                   'Y
  operand:         (suit * rank) list list * (suit * rank) list list * 
                   move list * int * 'Y
  in expression:
    get_score (loc',c :: lohc,lmoves',goal,e)
hw2.sml:198.29-198.78 Error: operator and operand don't agree [tycon mismatch]
  operator domain: (suit * rank) list list * (suit * rank) list * exn
  operand:         (suit * rank) list list * card * 'Z
  in expression:
    remove_card (lohc,c,e)
hw2.sml:192.27-198.78 Error: types of rules don't agree [tycon mismatch]
  earlier rule(s): (suit * rank) list list -> int
  this rule: move list -> 'Z
  in rule:
    :: (d,lmoves') =>
      (case d
        of Discard c => get_score (<exp>,<exp>,<exp>,<exp>,<exp>))
hw2.sml:192.27-198.78 Error: case object and rules don't agree [tycon mismatch]
  rule domain: (suit * rank) list list
  object: (suit * rank) list
  in expression:
    (case lcards
      of nil => score (lcards,goal)
       | :: (c,loc') =>
           if sum_cards <exp> > goal
           then score (<exp>,<exp>)
           else get_score (<exp>,<exp>,<exp>,<exp>,<exp>)
       | :: (d,lmoves') =>
           (case d
             of Discard <pat> => get_score <exp>))
val it = () : unit

我认为这是因为我使用了多个案例表达式。 任何帮助将不胜感激!

I'm trying to write a program in SML for the following problem:

A game is played with a card-list and a goal. The player has a list of held-cards, initially empty. The player
makes a move by either drawing, which means removing the first card in the card-list from the card-list and
adding it to the held-cards, or discarding, which means choosing one of the held-cards to remove. The game
ends either when the player chooses to make no more moves or when the sum of the values of the held-cards
is greater than the goal. Write a function officiate, which “runs a game.” It takes a card list (the card-list) a move list
(what the player “does” at each point), and an int (the goal) and returns the score at the end of the
game after processing (some or all of) the moves in the move list in order. Use a locally defined recursive
helper function that takes several arguments that together represent the current state of the game. As
described above:

  • The game starts with the held-cards being the empty list.
  • The game ends if there are no more moves. (The player chose to stop since the move list is empty.)
  • If the player discards some card c, play continues (i.e., make a recursive call) with the held-cards
    not having c and the card-list unchanged. If c is not in the held-cards, raise the IllegalMove
    exception.
  • If the player draws and the card-list is (already) empty, the game is over. Else if drawing causes
    the sum of the held-cards to exceed the goal, the game is over (after drawing). Else play continues
    with a larger held-cards and a smaller card-list.

And this is my solution:

datatype suit = Clubs | Diamonds | Hearts | Spades
datatype rank = Jack | Queen | King | Ace | Num of int 
type card = suit * rank

datatype move = Discard of card | Draw 

exception IllegalMove

fun remove_card (cs, c, e) =
    let
       fun delete_it (cs, c, e, count, acs) =
           case cs of
           [] => if count = 0 then raise e else acs
         | cp::cs' => if cp = c andalso count = 0
                      then delete_it (cs', c, e, count + 1, acs)
                      else
                          if cp = c then delete_it (cs', c, e, count + 1, [cp] @ acs) else delete_it (cs', c, e, count, [cp] @ acs)                
    in
       delete_it (cs, c, e, 0, [])
    end 

fun sum_cards (loc) =
    let
        fun sum_it (loc, sum) =
           case loc of
           [] => sum
         | c::loc' => sum_it (loc', sum + card_value (c))
    in
        sum_it (loc, 0)
    end 

fun score (loc, goal) =
    let
        val sum = sum_cards (loc)
        val all_same = all_same_color (loc)         
    in
        let
           fun prem_score (sum, goal) =
               if sum > goal
               then 3 * (sum - goal)
               else goal - sum     
        in
           let 
              val pre_score = prem_score (sum, goal)
              fun final_score (all, pre) =
                  if all
                  then pre div 2
                  else pre
        in
           final_score (all_same, pre_score)
        end         
    end
    end

fun officiate (loc, lom, goal) =
    let
    fun get_score (lcards, lohc, lmoves, goal, e) =
        case lmoves of
        [] => score (lcards, goal)
          | Draw::lmoves' => case lcards of
                   [] => score (lcards, goal)
                 | c::loc' => if sum_cards (c) > goal
                          then score (lcards, goal)
                          else get_score (loc', c::lohc, lmoves', goal, e)
          | d::lmoves' => case d of
                 Discard c => get_score (loc, remove_card (lohc, c, e), lmoves', goal, e)        
    in
    get_score (loc, [], lom, goal, IllegalMove)
    end                    

Ihe function sum_cards returns the values sum of the given card lists. score function returns the score of the game, while remove_card returns a list of cards minus the card provided. All these functions are working perfectly, but the problem is in the officiate function as I tried to use another two helper functions but without luck. This is the error log:

hw2.sml:196.17-196.60 Error: operator and operand don't agree [tycon mismatch]
  operator domain: (suit * rank) list * (suit * rank) list list * 'Z * int * 
                   'Y
  operand:         (suit * rank) list list * (suit * rank) list list * 
                   move list * int * 'Y
  in expression:
    get_score (loc',c :: lohc,lmoves',goal,e)
hw2.sml:198.29-198.78 Error: operator and operand don't agree [tycon mismatch]
  operator domain: (suit * rank) list list * (suit * rank) list * exn
  operand:         (suit * rank) list list * card * 'Z
  in expression:
    remove_card (lohc,c,e)
hw2.sml:192.27-198.78 Error: types of rules don't agree [tycon mismatch]
  earlier rule(s): (suit * rank) list list -> int
  this rule: move list -> 'Z
  in rule:
    :: (d,lmoves') =>
      (case d
        of Discard c => get_score (<exp>,<exp>,<exp>,<exp>,<exp>))
hw2.sml:192.27-198.78 Error: case object and rules don't agree [tycon mismatch]
  rule domain: (suit * rank) list list
  object: (suit * rank) list
  in expression:
    (case lcards
      of nil => score (lcards,goal)
       | :: (c,loc') =>
           if sum_cards <exp> > goal
           then score (<exp>,<exp>)
           else get_score (<exp>,<exp>,<exp>,<exp>,<exp>)
       | :: (d,lmoves') =>
           (case d
             of Discard <pat> => get_score <exp>))
val it = () : unit

I think this is because I used multiple case expressions.
Any help will be appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文