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
答案 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.Vector
或Data.Vector.Unboxed
回答这个问题,因为我不认为这个问题在多维Data.Array.IArray
...
您可以在ViewL
中执行类似ViewR
和Data.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
由于tail
和init
是Data.Vector
的O(1)切片,因此懒惰只会根据需要查看矢量的多个元素。