如何使用视图模式语法编写此case表达式?

Rnh*_*joj 8 haskell pattern-matching

在我读完"了解你的Haskell以获得伟大的好处!" 中的RPN计算器示例之后.我想以更一般的方式自己重写它.

为了方便地扩展可用的功能,我将它们放在单独的列表中,并lookup使用ViewPatterns语法将模式与函数匹配.为了阅读输入read我写了这个:

parse xs x = case readMaybe x of
  Just x  -> Right (x : xs)
  Nothing -> Left "Syntax error
Run Code Online (Sandbox Code Playgroud)

但我宁愿避免使用case表达式并再次使用这样的视图模式:

parse xs (readMaybe -> Just x ) = Right (x : xs)
parse xs (readMaybe -> Nothing) = Left "Syntax error"
Run Code Online (Sandbox Code Playgroud)

但是后者我得到了这个错误: No instance for (Read a0) arising from a use of ‘readMaybe’

我不明白为什么.它们不相同吗?

整个代码在这里.

pig*_*ker 11

他们不等同.该case版本有一个readMaybe,视图模式版本有两个.对于每一个readMaybe,编译器必须推断哪个类型是尝试读取的目标.当代码说

parse xs x = case readMaybe x of
  Just x  -> Right (x : xs)
  Nothing -> Left "Syntax error
Run Code Online (Sandbox Code Playgroud)

GHC侦探注意到,在你的Just x情况下,x最终会被认为是xs,所以必须采取任何类型的元素xs.这是件好事.

但是当你写作

parse xs (readMaybe -> Just x ) = Right (x : xs)
parse xs (readMaybe -> Nothing) = Left "Syntax error"
Run Code Online (Sandbox Code Playgroud)

你创建了两个独立的find-the-target-type问题,每个问题都有一个问题readMaybe.其中第一个以与case案例相同的方式解决,但对于第二个,单独阅读,

parse xs (readMaybe -> Nothing) = Left "Syntax error"
Run Code Online (Sandbox Code Playgroud)

你不知道自己没有阅读是什么,也没有理由相信它与上面的那一行是一回事.

通常,除非只有一个感兴趣的结果,否则使用视图模式是不合适的.他们是错误的语法,如果你想要做一个中间计算一次,但结果分析成不止一例.我很高兴继续记录,因为这个原因我认为它们是错误的.

  • Rnhmjoj:你仍然可以使用 ViewPatterns,只需将 `(readMaybe -> Nothing)` 替换为 `_`。 (2认同)