2011-11-28 16 views
11

Öğeleri, oluşturuldukları sırada sık sık güncelleştirildiklerinden, dönüştürülebilir olması gereken bir ağaçtan, matlaştırılmış bir matris listesi oluşturuyor. ,map runSTArray STArrays'in bir listesi üzerinde mi?

doAll :: .. -> [ST s (STArray s (Int, Int) Int)] 

nedeni doğrudan doAll yinelemeli olarak adlandırılır, çünkü [UArray (Int,Int) Int] döndürmez listedeki matrislerin elemanları değiştirir ve yeni matrisleri ekler: Şimdiye kadar imzaya sahip bir özyinelemeli çözüm ile geldi . Matrisleri gereksiz yere dondurmak ve çözmek istemiyorum. Şimdiye kadar çok iyi. Ben ghci

runSTArray (matrices !! 0) 
runSTArray (matrices !! 1) 

içinde (tip Array (Int, Int) Int arasında) n-inci matrisi inceleyebilir ve aslında benim algoritması için doğru sonuçlar elde ederler. Ben liste üzerinde yinelemeli değerlendirmek veya bir sarılmış tek unsurları değerlendirmek için denemek çalışırsanız

map (runSTArray) matrices 

Couldn't match expected type `forall s. ST s (STArray s i0 e0)' 
      with actual type `ST s0 (STArray s0 (Int, Int) Int)' 

aynı sorun olur: Ancak, ben doAll tarafından döndürülen liste üzerinde runSTUArray eşleştirmek için bir yol bulamadık function

Birisi, neler olup bittiğini açıklıyor olabilir (forall anahtar sözcüğünün sonuçlarını anlamış değilim) ve listedeki dizileri nasıl değerlendirebilirim?

+2

http://www.mail-archive.com/[email protected]/msg47957.html –

cevap

10

gibi başka ST eylem değerleri işleyemez. İlk olarak, ST'nin nasıl çalıştığını bilmelisiniz. ST monadından salt koda ulaşmanın tek yolu, runST işlevi veya runSTArray gibi üzerine kurulu diğer işlevlerdir. Bunların hepsi forall s. biçimindedir. Bu, bir STArray'dan bir Dizi oluşturmak için, derleyicinin, runST içindeki s tür değişkeni için istediği her tür yerine geçebileceğini belirleyebilmesi gerektiği anlamına gelir.

Şimdi map :: (a -> b) -> [a] -> [b] işlevini göz önünde bulundurun. Bu, listedeki her öğenin tam olarak aynı türde (a) ve dolayısıyla da aynı s olduğunu gösterir. Ancak bu ek kısıtlama, derleyicinin s için diğer değerleri serbestçe kullanabilmesi gerektiğini bildiren runSTArray türünü ihlal eder.

Önce ST monad içinde dizi dondurmak için yeni bir fonksiyon tanımlayarak bu çalışabilirsiniz, daha sonra ortaya çıkan ST eylemi çalıştırın:

runSTArrays :: Ix ix => (forall s. [ST s (STArray s ix a)]) -> [Array ix a] 
runSTArrays arrayList = runST $ (sequence arrayList >>= mapM freeze) 

Not forallRankNTypes uzantısı gereklidir.

+0

Açıklama için teşekkürler, bu çok mantıklı. Yine de, runSTArrays'ınızdaki runST'yi kaldırmalı ve daha sonra ayrı ayrı aramak zorundayım. "ghc", bağlamı çıkaramaz ve ayrıca açık bir tür ek açıklama kabul etmez. – bbtrb

+0

Bunun için üzgünüz; Bu koda uygun tip ek açıklama ekledim. GHC, daha iyi türden ek açıklamaları (forall) çıkarmaz, bu yüzden el ile sağlanmalıdır. –

+0

"Dizi", programın "dizi içeriğini güncelleştirmek için bazı işlevleri" bulunacağı yer tutucu mu? – misterbee

4

Sadece tip sistemindeki sınırlamalara karşı çıktınız.

runSTArray'in daha yüksek bir sıralaması vardır. Durum türü değişkeni benzersiz olan bir ST eylemini iletmelisiniz. Ancak, Haskell'de normalde bu gibi değerlerin listelere girmesi mümkün değildir.

Her şey, ST eyleminde ürettiğiniz değerlerin oradan kaçamadığından emin olmak için akıllı bir şemadır. Yani, tasarımın bir şekilde kırılmış gibi görünüyor.

Bir öneri: Eğer bu ST güvenli hale getirir tip hile talihsiz bir sonucudur

sequence [ ... your ST s (STArray s x) ...] >>= processing 
    where 
    processing :: [STArray s x] -> ST s (your results) 
+1

Tasarımımın hangi açılardan kırılabileceğini merak ediyorum. haskell için oldukça yeni). Geçilmek ve değerlendirilmek üzere giderek değişen matrisler listesini nasıl yöneteceğinize dair bazı önerileriniz var mı? – bbtrb

+0

@bbtrb - Belki de tasarımın kendisi değil, “ST” nin bir listesiyle çalışmak arzusu. Temel olarak, bu matrisler değişebilir verilerdir ve bu, ST veya IO eylemleri dışında onlarla çalışamayacağınız (veya en azından olmamalı) anlamına gelir. Tam olarak, bu, John L'nin size söylediği gibi, runst * funtions ailesinin türü tarafından zorlanır. 'freeze', Haskell sistemine sadece matrisleri (ya da her neyse) salt okunur değerler olarak ele almak istediğinizi ve daha sonra ST eyleminde oluşturulan değerlerin (kopyalarının) kaçmasına izin vermenin bir yoludur. – Ingo

İlgili konular