Haskell模式匹配向量

mat*_*ias 4 haskell vector pattern-synonyms

是否可以在向量上使用列表样式模式匹配?

import qualified Data.Vector as V

f :: V.Vector a -> a
f (x:xs) = x 
Run Code Online (Sandbox Code Playgroud)

给出错误

ram*_*ion 7

-XViewPatterns 可以让你这样做:

{-# LANGUAGE ViewPatterns #-}
module VecViewPats where

import Data.Vector (Vector)
import qualified Data.Vector as V

uncons :: Vector a -> Maybe (a, Vector a)
uncons v = if V.null v
  then Nothing
  else Just (V.unsafeHead v, V.unsafeTail v)

vsum :: Num a => Vector a -> a
vsum (uncons -> Just (a,av)) = a + vsum av
vsum (uncons -> Nothing) = 0
Run Code Online (Sandbox Code Playgroud)

要么 -XLambdaCase

import Control.Category ((>>>))
-- ...
vsum :: Num a => Vector a -> a
vsum = uncons >>> \case
  Just (a,av) -> a + vsum av
  Nothing     -> 0
Run Code Online (Sandbox Code Playgroud)

但老实说,这似乎有点代码味道,因为你使用一个数据结构(Vector)作为另一个([]),这表明你可能选择的数据结构是关闭的.

如果您真的只想将其视为某些算法的列表,为什么不使用toList

  • 或者你可以使用模式同义词:`pattern x ::: xs < - (uncons - > Just(x,xs))` (2认同)

L.-*_*hen 5

@Cactus 指出-XPatternSynonym(在 7.8 中引入)结合-XViewPattern可用于向量的模式匹配。我在这里进一步扩展他的评论。

pattern Empty <- (V.null -> True) 
Run Code Online (Sandbox Code Playgroud)

以上定义了Empty空向量的模式同义词。该Empty模式使用视图模式 ( V.null -> True)与空向量匹配。但是,它不能用作其他地方的表达式,即单向同义词,因为系统并不真正知道什么Empty是向量(我们只知道null v是,True但也可能有其他向量True)。

为了解决这个问题,where可以添加一个子句,指定 Empty 实际上是一个空向量,即双向同义词,以及类型签名:

pattern Empty :: Vector a
pattern Empty <- (V.null -> True) where Empty = V.empty 
Run Code Online (Sandbox Code Playgroud)

此模式同义词可用于在uncons没有 if 表达式的情况下进行定义:

uncons :: Vector a -> Maybe (a, Vector a)
uncons Empty = Nothing
uncons v     = Just (unsafeHead v, unsafeTail v)
Run Code Online (Sandbox Code Playgroud)

我们uncons用来定义单向同义词。请注意,我不会将其设为双向,因为cons矢量代价高昂:

pattern (:<|)  :: a -> Vector a -> Vector a
pattern x :<| xs <- (uncons -> Just (x, xs))
Run Code Online (Sandbox Code Playgroud)

无论如何,我们终于能够像列表一样对向量进行模式匹配:

vsum :: Num a => Vector a -> a 
vsum Empty = 0
vsum (x :<| xs) = x + vsum xs
Run Code Online (Sandbox Code Playgroud)

完整的代码在这里