我構建了一個函數,用於使用ST-Monad和非盒裝STArrays(STUArray)查找矩陣的行列式。該類型的矩陣如下:使用STUArray找不到功能的合適簽名(GHC也不能)
newtype Matrix e = Matrix (Array Int (UArray Int e))
即,包含含有元素不可改變裝箱陣列的不可變陣列。這將要求我將Predicate IArray UArray e
添加到處理Matrix
的函數中,這又需要FlexibleContexts
。好的,完成了。
用來計算行列式的函數具有以下特徵:
detST :: (IArray UArray e, MArray (STUArray s) e (ST s),
Num e, Eq e, Division e)
=> Array Int (UArray Int e) -> ST s e
我需要還添加謂詞MArray (STUArray s) e (ST s)
因爲內部的陣列被轉換成可變陣列(外盒裝,內裝箱) 。
此功能可用於像這樣:
main = do
let [email protected](Matrix x) = matrix [ [1,-2,3,234]
, [5,2,3,-3]
, [7,18,3,40]
, [2,9,71,0] ]
d = runST (detST x) :: Int -- needed for type check, ambiguous otherwise
print d
工程,細。但看看它有多醜!當然,我不想放棄Matrix
的內部結構(至少不會超過我的函數所附帶的謂詞已經使我)。我想定義以下功能:
det :: Matrix e -> e
而我不能。
我想沒有一個適當的簽名:
det (Matrix arr) = runST (detST arr)
失敗。公平的,我會讓我的大腦工作:detST
要求IArray UArray e, MArray (STUArray s) e (ST s), Num e, Eq e, Division e
,det
也是這樣,不是嗎?
det :: (IArray UArray e, MArray (STUArray s) e (ST s),
Num e, Eq e, Division e) => Matrix e -> e
失敗。但我不知道如何。該GHC(7.4.2)給我的信息是:
Could not deduce (MArray (STUArray s) t (ST s))
arising from a use of `detST'
但確切項是謂詞!
GHC提示:
add (MArray (STUArray s) t (ST s)) to the context of
a type expected by the context: ST s t
or the inferred type of
det :: (Eq t, Num t, IArray UArray t, Division t) => Matrix t -> t
or add an instance declaration for (MArray (STUArray s) t (ST s))
好。至於我的理解,我已經完成了第一件事。此外,還存在一個實例(MArray ...)
(否則,我怎麼能在main ?!中成功使用它)。
我不確定這裏有什麼問題。我相信它與s
中的「隱藏」ST狀態有關,並且detST
的s是s
的s
中的s
會是det
,但我不知道如何爲此寫入類型。
什麼是det
的正確定義 - 爲什麼?!
該程序沒有det
編譯罰款僅使用FlexibleContexts
,沒有警告與-Wall
。完整的源代碼可以在as a gist here。
開始 - 爲什麼不只是使用UArray索引(Int,Int)而不是數組數組? – 2013-04-05 07:54:56
這樣我就可以輕鬆切換行。無論如何,這個程序當然還有其他可能的版本。但是我想知道爲什麼我不能定義這個特定的功能以及它有什麼問題。 – scravy 2013-04-05 07:56:18
你能告訴我們'detST'的定義,以便我們可以測試你的代碼嗎?我不太明白爲什麼它需要在ST中。 – 2013-04-05 08:01:53