返回multable数组和列表的递归函数

时间:2016-11-02 23:27:25

标签: haskell monads composition st-monad

我正在尝试构建一个递归函数,为简单起见,我们假设它需要一个列表并构建一个数组和一个列表。因为我需要在构建数组时读取和写入数组,所以我使用了一个可变数组,因此我可以进行恒定的读写操作。所以签名和函数看起来如下:

f :: [a] -> ST s ([a], STArray s Int a) -> ST s ([a], STArray s Int a)
f (x:xs) curr_arr = 
  case blah of
    ... -> f xs new_arr
f [] curr_arr = curr_arr

我想要一个带有以下签名的函数h

h :: Int -> Int -> a -> [a] -> (Array Int a, [a])

我希望它有大致以下的实现:

h lbound ubound default_a xs = g (f xs (newArray lbound ubound default_a))

问题是,我需要一个带有此签名的函数g

ST s ([a], STArray s Int a) -> (Array Int a, [a])

但我似乎无法将runSTrunSTArray合在一起来实现这一目标。

无论如何都要实施g,或者我应该首先使f的签名完全不同?

1 个答案:

答案 0 :(得分:0)

您应该使用Monad ST s实例来实现对f的递归调用(及其结果的组合):更改f' s输入

f :: [a] -> ([a], STArray s Int a) -> ST s ([a], STArray s Int a)

这意味着f中的递归调用看起来像

f xs curr = do
    xs' <- ...
    curr' <- ...
    next <- f xs' curr'
    combine curr next

然后runST它在h完成(runSTArray并不直接在这里工作,因为你的[a]也在旁边):< / p>

h lo hi x0 xs = runST $ do
    curr <- newArray lo hi x0
    (ys, mArr) <- f xs (xs, curr)
    arr <- freeze mArr
    return (ys, arr)

这是有效的,因为在最后一个表达式ys :: [a]arr :: Array Int a中,所以两者都不取决于s的选择。