Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays haskell中是否有一个功能可以像accumArray和foldr一样工作?_Arrays_Haskell_Fold - Fatal编程技术网

Arrays haskell中是否有一个功能可以像accumArray和foldr一样工作?

Arrays haskell中是否有一个功能可以像accumArray和foldr一样工作?,arrays,haskell,fold,Arrays,Haskell,Fold,让我调用函数AccumArray accumrArray :: (e' -> e -> e) An accumulating function -> e A default element -> (i, i) The bounds of the array -> [(i, e')] List of associati

让我调用函数AccumArray

accumrArray :: 
              (e' -> e -> e) An accumulating function
           -> e              A default element 
           -> (i, i)         The bounds of the array 
           -> [(i, e')]      List of associations 
           -> a i e          The array

accumrArray  (:) [] (1,2) [(1,1),(2,2),(2,3)]  === array [(1,[1]), (2,[2,3])]
head $ (accumrArray (:) [] (1,1) [(1,x)|x<-[4..]]) ! 1 === 4
AccumArray::
(e'->e->e)一个累加函数
->e默认元素
->(i,i)数组的界
->[(i,e')]协会名单
->a对数组进行加密
AccumArray(:)[(1,2)[(1,1)、(2,2)、(2,3)]==数组[(1[1]),(2[2,3])]

head$(accurmrray(:)[(1,1)[(1,x)| x不是最有效的,但是。。。
accumArray f x b l=accumArray(翻转f)x b(反向l)

真奇怪……我几天前为其他人编写了此函数。该函数最初出现在LML中(我相信),但从未进入Haskell阵列库

给你:

{-# LANGUAGE ScopedTypeVariables #-}
import Data.Array
import System.IO.Unsafe
import Data.IORef
import Data.Array.MArray
import Data.Array.Base
import Control.Monad
import Data.Array.IO

accumArrayR :: forall a e i. Ix i => (a -> e -> e) -> e -> (i,i) -> [(i,a)] -> Array i e
accumArrayR f e bounds@(l,u) assocs = unsafePerformIO $ do
  ref <- newIORef assocs
  arr <- newArray_ bounds
  let _ = arr :: IOArray i e
  let n = safeRangeSize (l,u)
  let elem x = unsafePerformIO $ do
                  ass <- readIORef ref
                  let loop [] = writeIORef ref [] >> return e
                      loop ((y,a):rest) = do
                         let ix = safeIndex bounds n y
                         let r = f a (elem x)
                         unsafeWrite arr ix r
                         if (ix == x)
                            then writeIORef ref rest >> return r
                            else loop rest
                  loop ass
  forM_ [0..n] $ \ix -> unsafeWrite arr ix (elem ix)
  unsafeFreeze arr
{-#语言范围的TypeVariables}
导入数据。数组
导入System.IO不安全
导入数据.IORef
导入Data.Array.MArray
导入Data.Array.Base
进口管制
导入Data.Array.IO
accumArrayR::对于所有a e i.Ix i=>(a->e->e)->e->(i,i)->[(i,a)]->数组i e
accumArrayR f e bounds@(l,u)assocs=未安全性能$do
ref>返回r
埃尔斯环休息
环驴
表格[0..n]$\ix->unsafeWrite arr ix(elem ix)
不安全
读者面临的挑战:使用
Accumarayr
实现图形的线性时间深度优先搜索

Edit我应该提到,该函数并不像编写的那样是线程安全的。将
IORef
转换为
MVar
可以修复它,但可能有更好的方法。

我认为

accumrArray f x b l = accumArray (flip f) x b (reverse l)
这确实是最好的解决方案(归功于sclv的答案)

它所谓的“低效”来自这样一个事实,即
foldr
从右向左应用函数
f

但是,由于
accumArray
是严格的,
l
永远不能是无限的,否则程序将不正确。它永远不会终止


因此,
foldl(flip f)
foldr

一样好,但它无法处理无限列表(l)通过谷歌搜索lml和accumArray让我看到了1993年的邮件列表历史:我是唯一一个对
loop ass
感到惊讶的人吗?