(不)在元组上使用惰性模式匹配的情况

Jus*_* L. 7 haskell pattern-matching

根据我的理解,元组上的延迟模式匹配只是推迟(,)构造函数的解析......如果我们立即使用这两个字段,那么真的有任何缺点吗?无论如何它都会得到解决......

有没有理由使用懒惰模式匹配?

foo ~(x, y) = x + y
-- vs
foo (x, y)  = x + y
Run Code Online (Sandbox Code Playgroud)

你何时喜欢使用第二个?

编辑:我特别感兴趣的是只有一种模式并且模式总是匹配的情况.

Jon*_*rdy 7

如果您想在惰性模式中进行任何严格匹配,则不希望使用延迟模式匹配.例如,给定以下定义:

foo' (Just x, Just y) = Just (x + y)
foo' _ = Nothing

foo ~(Just x, Just y) = Just (x + y)
foo _ = Nothing
Run Code Online (Sandbox Code Playgroud)

foo' (Just 5, Nothing)给出Nothing,但foo (Just 5, Nothing)抛出一个运行时错误 - 并另外给出一个编译时警告,该_情况是多余的,因为~(…)案例是无可辩驳的.

当您知道模式将始终匹配时,使用延迟模式匹配几乎是有意义的,这基本上意味着您只使用单构造函数类型,例如(,)整个延迟模式.


dan*_*iaz 7

一个例子是州议员.状态monad的严格/惰性版本通过它们在绑定期间对(值,状态)对进行模式匹配来区分.

严格的州Monad:

m >>= k  = StateT $ \ s -> do
    (a, s') <- runStateT m s
    runStateT (k a) s
Run Code Online (Sandbox Code Playgroud)

懒惰状态monad:

m >>= k  = StateT $ \ s -> do
    ~(a, s') <- runStateT m s
    runStateT (k a) s'
Run Code Online (Sandbox Code Playgroud)

懒惰状态monad中的惰性模式匹配允许您定义像这样的奇怪程序(取自Melding Monads的这篇博文):

pro :: State [Bool] ()
pro = do
   pro
   s <- get
   put (True : s)
Run Code Online (Sandbox Code Playgroud)

该程序True使用"头递归" 生成一个懒惰的无限值列表.使用严格状态monad的相同程序会在生成任何内容之前将堆栈清空.