数组的模式匹配

时间:2016-07-31 20:14:50

标签: arrays haskell

Haskell在Data.Array.IArray中提供了不可变数组的Array类型。这允许在功能代码中使用数组。是否可以将Array与模式匹配,与列表可能的方式相同?

我希望以下代码能够正常运行......

function :: Ix a => Array a b -> ...

function [| x |]         = ... -- matches if arg has one element
function [| x, y |]      = ... -- matches if arg has two elements
function [| x, ..., y |] = ... -- matches if arg has more than 3 elements and
                               -- binds the first and last element with x and y

注意:此功能存在于Rust语言中,请参阅https://doc.rust-lang.org/book/slice-patterns.html

2 个答案:

答案 0 :(得分:2)

首先,请注意Haskell数组可能是多维的。

您可以像这样编写示例函数:

import Data.Array.IArray
import Data.Ix

foo arr
  | first == last = print x      -- single element case
  | otherwise     = print (x,y)  -- more than one element case
  where (first,last) = bounds arr
        x = arr ! first
        y = arr ! last

答案 1 :(得分:1)

我将为Data.VectorData.Vector.Unboxed回答这个问题,因为我不认为这个问题在多维Data.Array.IArray ...

方面真的有意义

您可以在ViewL中执行类似ViewRData.Sequence的操作。适应它,你可以

data ViewL a
    = EmptyL        -- ^ empty vector
    | a :< Vector a -- ^ leftmost element and the rest of the vector

data ViewR a
    = EmptyR        -- ^ empty vector
    | Vector a :> a -- ^ rest of the vector and the rightmost element

然后,您可以定义函数

viewl :: Vector a -> ViewL a
viewl v | null v = EmptyL
        | otherwise = head v :< tail v 

viewr :: Vector a -> ViewR a
viewr v | null v = EmptyR
        | otherwise = init v :> last v 

viewlr :: Vector a -> (ViewL a, ViewR a)
viewlr v = (viewl v, viewr v) -- or `viewl &&& viewr` if you like Control.Arrows

并使用ViewPatterns扩展程序:

function :: Vector a -> ...
function (viewl -> x :< EmptyL)      = ... -- matches if arg has one element
function (viewl -> x :< y:< EmptyL)  = ... -- matches if arg has two elements
function (viewlr -> (x :< _, _ :> y) = ... -- matches `x` and `y` to the first and
                                           -- last elements
function (viewlr -> (x :< _ :< _ :< _, _ :> y) = ... -- matches if arg has more
                                                     -- than 3 elements and binds 
                                                     -- the first and last element
                                                     -- with x and y

由于tailinitData.Vector的O(1)切片,因此懒惰只会根据需要查看矢量的多个元素。