【问题标题】:Haskell List With Guards errorHaskell List With Guards 错误
【发布时间】:2012-12-18 05:47:38
【问题描述】:

我正在尝试在 haskell 中编写一个非常简单的函数来根据输入更改列表中的值,如下所示

update_game :: [Int] -> Int -> Int -> [Int]
update_game (x:xs) row take_amnt | row == 1 = x - take_amnt:xs
                                 | row == 2 = x : head(xs) - take_amnt : tail(xs)
                                 | row == 3 = x : head(xs) : last(xs) - take_amnt`

前两种情况正常,但最后一种情况给我带来了问题,我不知道为什么,我得到的错误是:

http://i.stack.imgur.com/jpT8b.png

http://i.stack.imgur.com/tlz5t.png

【问题讨论】:

  • 在 Windows 控制台中,您可以通过单击窗口图标、选择“标记”、进行选择并按 Enter 将其复制到剪贴板来复制文本。

标签: list haskell guard list-comprehension take


【解决方案1】:

: 的第二个参数应该是一个列表,但last(xs) - take_amnt 显然只产生一个元素。试试

row == 3 = x : head(xs) : [last(xs) - take_amnt]

【讨论】:

    【解决方案2】:

    “:”中的第二个参数应该是一个列表,last(xs) - take_amnt 只给出一个元素。

    将其包裹在“[]”中,即[last(xs) - take_amnt]

    【讨论】:

      【解决方案3】:
      last(xs) - take_amnt
      

      是一个Int,但(:) 的第二个参数必须是一个列表,因为(:) :: a -> [a] -> [a]

      如果您的列表总是三个元素长(但您可能应该使用元组而不是列表),看起来,将其包装在 [ ] 中会以正确的语义解决它,

      update_game :: [Int] -> Int -> Int -> [Int]
      update_game (x:xs) row take_amnt | row == 1 = x - take_amnt:xs
                                       | row == 2 = x : head(xs) - take_amnt : tail(xs)
                                       | row == 3 = x : head(xs) : [last(xs) - take_amnt]
      

      但是,最好进行相应的模式匹配

      update_game [x,y,z] 1 take_amnt = [x - take_amnt, y, z]
      update_game [x,y,z] 2 take_amnt = [x, y - take_amnt, z]
      update_game [x,y,z] 3 take_amnt = [x, y, z - take_amnt]
      update_game _       _ _         = error "Invalid input"
      

      或者在没有模式匹配的情况下使其通用

      update_game xs index take_amnt = zipWith (-) xs (replicate (index-1) 0 ++ take_amnt : repeat 0)
      

      【讨论】:

      • 您的替代 update_game 定义会产生错误,而原始函数会为 update_game [1] 1 0 产生 [1]
      • 嗯,它基于明确提到的假设,即列表总是恰好包含三个元素。
      • @FrerichRaabe 如果我没记错的话,在原始代码中这会导致head [] 被调用,这会导致错误。
      • @WillNess:在update_game [1] 1 0 中,row == 1 成立,因此使用x - take_amnt:xs;没有head 打电话给那里。
      猜你喜欢
      • 1970-01-01
      • 2015-02-04
      • 2014-10-02
      • 2016-04-13
      • 1970-01-01
      • 2020-02-07
      • 2019-04-26
      • 2012-03-09
      • 1970-01-01
      相关资源
      最近更新 更多