2012-10-19 16 views
19

Standart dizi paketindeki sınırlı dizilere benzer bir şey elde etmek, ancak repa dizilerini kullanmak istiyorum.Sınırlı bir veri türü tarafından dizine alınmış diziler onarılsın mı?

Bunu başarmanın güzel ve temiz yolu nedir? Ayrıca

import Data.Array.Repa 

data C = A | F | L deriving (Eq,Enum,Ord,Bounded,Show) 

data Ballot c = Ballot { 
    vote::Array U (Z :. Int) Int 
    } deriving Show 

mkBallot::(Eq c ,Enum c,Ord c, Bounded c, Show c) => c -> Ballot c 
mkBallot c = Ballot $ fromListUnboxed (Z :. max) (genSc c) 
where 
    max = (fromEnum (maxBound `asTypeOf` c)) + 1 

genSc::(Eq c,Enum c,Ord c,Bounded c,Show c) => c -> [Int] 
genSc c = [ f x | x <- enumFrom (minBound `asTypeOf` c) , let f v = if x == c then 1 else 0] 

showScore c b = index (vote b) (Z :. ((fromEnum c))) 

I (sh için bir Shape örneği türetmek için çalıştık:

Bu

Denedim ama sınırların kontrol özel işlevler her şeyi sarma daha iyi bir yolu olmalı budur. C) Ancak hiçbir boşuna, veri tipim için Shape sınıfında bildirilen bazı arabirimlerin nasıl uygulanacağı konusunda kafamı alamıyorum. Soruyu bir başkasının bir yolu olduğu ümidiyle yazıyorum, ama değilse tekrar deneyeceğim. Teşekkür ederim!

cevap

2

Sınırlı numaranızdaki sarıcı için bir şekil örneği oluşturabilirsiniz. Bunun en iyi yol olduğundan emin değilim, ama ne istersen onu yapıyor, bence.

{-# LANGUAGE ScopedTypeVariables #-} 

import Data.Array.Repa 

Burada sınırlanmış şeyler üzerinde bir şekil örneği oluşturuyoruz. "Tam" diziler için bir endeks sonuna ihtiyacımız var. Bunun üzerine

data Idx a = Idx a | EOI 
      deriving (Eq, Ord, Show) 

fromIdx :: forall a . (Bounded a, Enum a) => Idx a -> Int 
fromIdx EOI = fromEnum (maxBound :: a) - fromEnum (minBound :: a) + 1 
fromIdx (Idx x) = fromEnum x - fromEnum (minBound :: a) 

toIdx :: forall a . (Bounded a, Enum a) => Int -> Idx a 
toIdx i | i < 0 = error "negative index" 
toIdx i = case compare i range of 
    LT -> Idx $ toEnum (i + fromEnum (minBound :: a)) 
    EQ -> EOI 
    GT -> error "out of range" 
    where 
    range = fromEnum (maxBound :: a) - fromEnum (minBound :: a) + 1 

instance (Bounded a, Enum a, Ord a) => Shape (Idx a) where 
    rank _ = 1 
    zeroDim = Idx minBound 
    unitDim = Idx $ succ minBound 
    intersectDim EOI n = n 
    intersectDim n EOI = n 
    intersectDim (Idx n1) (Idx n2) = Idx $ min n1 n2 
    addDim = error "undefined" 
    size = fromIdx 
    sizeIsValid _ = True 
    toIndex _ n = fromIdx n 
    fromIndex _ i = toIdx i 
    inShapeRange _ _ EOI = error "bad index" 
    inShapeRange n1 n2 n = n >= n1 && n <= n2 
    listOfShape n = [fromIdx n] 
    shapeOfList [i] = toIdx i 
    shapeOfList _ = error "unsupported shape" 
    deepSeq (Idx n) x = n `seq` x 
    deepSeq _ x = x 

, sandık kısmı kolay ve temiz:

data C = A | F | L deriving (Eq, Enum, Ord, Bounded, Show) 

data Ballot c = Ballot { vote :: Array U (Idx c) Int 
         } deriving Show 

mkBallot :: (Eq c, Enum c, Ord c, Bounded c, Show c) => c -> Ballot c 
mkBallot c = Ballot $ fromListUnboxed EOI vec 
    where 
    vec = map (fromEnum . (== c)) [minBound .. maxBound] 
+0

Ben buna bir göz alacak. – user1105045

İlgili konular