我如何改进我的Haskell代码并使其工作?



在我的代码中,我用一个FEN字符串调用validateFEN函数。一个Fen字符串看起来像这样,例如:

",w84,w41,w56,w170,w56,w41,w84,/,,w24,w40,w17,w40,w48,,/,,,w16,w16,w16,,,/,,,,,,,,/,,,,,,,,/,,,,,,,,/,,,b1,b1,b1,,,/,,b3,b130,b17,b130,b129,,/,b69,b146,b131,b170,b131,b146,b69,"

函数应该接受字符串并检查它是否是一个FEN字符串。它怎么知道它是不是一个FEN字符串?→我的字符串有9行9列。我不需要检查棋子(例如:w86)是否在正确的位置。

validateFEN' b = help3 (filter (x -> x == ',' || x == '/' ) b)
help3 b =  (if help1 b == True then (if head (drop 8 b) == '/' then help3 (drop 9 b) else False) else False )
help1 b = help2 (take 8 b)
help2 b = foldr (+) 0 (map (x -> if x == ',' then 1 else 0 )b) == 8

为什么我总是得到空列表的错误?

例外:序曲。标题:空列表

我明白我的代码没有停止。程序不知道什么时候字符串是"正确的">

有更短更简单的方法吗?

重用现有库函数的一种方法是使用stripPrefix

help3 s = case stripPrefix ",,,,,,,,/" s of
Nothing -> False
Just s' -> help3 s'

当然,您仍然需要处理最后一种情况,其中没有终止/。这可以通过一个额外的子句来完成:

help3 ",,,,,,,," = True
help3 s = {- ... -}

您可能想要考虑validateFEN'是否应该对空字符串有类似的特殊情况。

但是我强烈建议首先不要实现validateFEN'。我猜计划大概是这样的:

  1. 检查字符串是否为有效的FEN
  2. 处理字符串,假设为fenness

相反,我推荐以下方法:

  1. 将字符串解析为本机数据结构,以表示FEN字符串中可用的信息。
  2. 处理本地结构

步骤1,如果使用标准解析解决方案编写,将"意外地"验证字符串——即运行解析器将返回类似Either Error FEN的内容,您可以对其进行模式匹配,以发现字符串是无效的,或者它是有效的,并且已被转换为更习惯的表示。

最新更新