Arrays 阵列的模式匹配

Arrays 阵列的模式匹配,arrays,haskell,Arrays,Haskell,Haskell在Data.Array.IArray中提供了一种不可变数组的类型Array。这允许在函数代码中使用数组。是否可以将Arrays与模式匹配,与列表匹配的方式相同 我想下面的代码工作 function :: Ix a => Array a b -> ... function [| x |] = ... -- matches if arg has one element function [| x, y |] = ... -- matches if

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

我想下面的代码工作

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语言中,请参见首先,注意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

我将为
Data.Vector
Data.Vector.unbox
回答这个问题,因为我认为这个问题在多维
Data.Array.IArray
方面没有意义

您可以在
Data.Sequence
中执行类似于
ViewL
ViewR
的操作。调整一下,你可以

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
数据视图
=EmptyL--^空向量
|a:<向量a--^最左边的元素和向量的其余部分
数据视图a
=EmptyR--^empty向量
|向量a:>a--^向量的其余部分和最右边的元素
然后,您可以定义函数

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
viewl::Vector a->viewl a
viewl v | null v=EmptyL
|否则=头部v:<尾部v
viewr::向量a->viewr a
viewr v | null v=EmptyR
|否则=初始v:>最后一个v
viewlr::向量a->(ViewL a,ViewR a)
viewlr v=(viewl v,viewr v)--或'viewl&&&viewr',如果您喜欢控件。箭头
并将其与扩展一起使用:

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
函数::向量a->。。。
函数(viewl->x:x:(x:<\uu,\u:>y)=…--将'x'和'y'匹配到第一个和第二个
--最后要素
函数(viewlr->(x:<\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
--超过3个元素并绑定
--第一个也是最后一个元素
--用x和y

因为
tail
init
是O(1)对于
Data.Vector
,这会根据需要懒洋洋地查看向量中的元素。

我不认为
Data.Array.IArray
提供了任何内置的方法来实现这一点,但通过和扩展,您可能可以自己实现类似的东西。您也可以使用防护而不是模式来实现这一点。事实上,我认为
Ix
type类指定了如何将数组的索引映射到连续整数。