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

时间:2015-02-26 21:26:26

标签: haskell pattern-matching

在我阅读了RPN calculator中的一个例子之后,#34;了解你是一个非常好的Haskell!"我想以更一般的方式自己重写它。

为了轻松扩展可用的功能,我将它们放在单独的列表中,并使用lookup语法与ViewPatterns函数匹配。要用read读取输入,我写了这个:

parse xs x = case readMaybe x of
  Just x  -> Right (x : xs)
  Nothing -> Left "Syntax error

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

parse xs (readMaybe -> Just x ) = Right (x : xs)
parse xs (readMaybe -> Nothing) = Left "Syntax error"

然而,后者我收到此错误: No instance for (Read a0) arising from a use of ‘readMaybe’

我不明白为什么。 Aren他们是等同的?

整个代码为here

1 个答案:

答案 0 :(得分:11)

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

parse xs x = case readMaybe x of
  Just x  -> Right (x : xs)
  Nothing -> Left "Syntax error

GHC侦探注意到,在Just x案例中,x最终与xs有关,因此必须采用xs元素所具有的任何类型。这是一项很好的工作。

但是当你写作

parse xs (readMaybe -> Just x ) = Right (x : xs)
parse xs (readMaybe -> Nothing) = Left "Syntax error"

您创建了两个单独的find-the-target-type问题,每个问题用于readMaybe。其中第一个问题的解决方式与case情况相同,但对于第二个问题,单独阅读,

parse xs (readMaybe -> Nothing) = Left "Syntax error"

没有任何线索是什么你没有阅读,没有理由相信它与上面的行是一回事。

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