我有一個編寫簡單函數時沒有太多重複自己的問題,下面是一個簡化示例。我試圖編寫的真正的程序是來自python的BI服務器的內存數據庫的端口。實際上有更多不同的類型(大約8個)和更多的邏輯,大部分可以表示爲對多態類型操作的函數,如向量a,但仍然有些邏輯必須處理不同類型的值。對基本類型的有限域的容器進行動態類型編寫
由於效率原因,單獨包裝每個值(使用[(Int,WrappedValue)]類型)不是一個選項 - 在實際代碼中,我使用的是非盒裝向量。
type Vector a = [(Int, a)] -- always sorted by fst
data WrappedVector = -- in fact there are 8 of them
FloatVector (Vector Float)
| IntVector (Vector Int)
deriving (Eq, Show)
query :: [WrappedVector] -> [WrappedVector] -- equal length
query vectors = map (filterIndexW commonIndices) vectors
where
commonIndices = intersection [mapFstW vector | vector <- vectors]
intersection :: [[Int]] -> [Int]
intersection = head -- dummy impl. (intersection of sorted vectors)
filterIndex :: Eq a => [Int] -> Vector a -> Vector a
filterIndex indices vector = -- sample inefficient implementation
filter (\(idx, _) -> idx `elem` indices) vector
mapFst :: Vector a -> [Int]
mapFst = map fst
-- idealy I whould stop here, but I must write repeat for all possible types
-- and kinds of wrapped containers and function this:
filterIndexW :: [Int] -> WrappedVector -> WrappedVector
filterIndexW indices vw = case vw of
FloatVector v -> FloatVector $ filterIndex indices v
IntVector v -> IntVector $ filterIndex indices v
mapFstW :: WrappedVector -> [Int]
mapFstW vw = case vw of
FloatVector v -> map fst v
IntVector v -> map fst v
-- sample usage of query
main = putStrLn $ show $ query [FloatVector [(1, 12), (2, -2)],
IntVector [(2, 17), (3, -10)]]
我怎樣才能表達不包裝和展開像mapFstW和filterIndexW功能,這樣的代碼?
這很好地概括了真正的問題(有一點Data.Typeable的幫助),謝謝! –
很高興聽到這是有幫助的! –