2011-12-24 14 views
5

Repa --- Okuma örneği nasıl yapılır?

type Configuration = Array DIM1 (Double, Double, Double) 

oku örneğidir yapmak için en iyi yolu nedir? Bu yüzden daha sonra Okuma'nın bir örneği olarak

türetilebilir.

+0

"Tam" Okuma örneği oluşturamadığınızdan şüpheleniyorum. Genellikle, yazarın mantıklı olduğuna inandığında, önemli veri türleri zaten Okuma örneklerine sahip olacaktır. Repa'da bulunan Array türü, bileşenleri içinde daha yüksek mertebeden fonksiyonlara sahiptir - “Generator” ve “Range” ler okunamayan örneklerdir. Yapmanız gereken doğru şey, verilerinizi daha basit bir formatta serileştirmek/serileştirmek olduğunu düşünürdüm. –

cevap

6

Böyle bir örnek, genellikle kaçınmanız gereken bir orphan instance olacaktır. Ancak, bunu yazmak için oldukça basit:

{-# LANGUAGE TypeOperators #-} 

import Data.Array.Repa (Array, Shape, Elt, Z(..), (:.)(..)) 
import qualified Data.Array.Repa as R 

instance Read Z where 
    readsPrec _ r = do 
    ("Z", s) <- lex r 
    return (Z, s) 

instance (Read tail, Read head) => Read (tail :. head) where 
    readsPrec d = 
    readParen (d > prec) $ \r -> do 
     (tl, s) <- readsPrec (prec + 1) r 
     (":.", t) <- lex s 
     (hd, u) <- readsPrec (prec + 1) t 
     return (tl :. hd, u) 
    where prec = 3 

instance (Shape sh, Read sh, Elt a, Read a) => Read (Array sh a) where 
    readsPrec d = 
    readParen (d > app) $ \r -> do 
     ("Array", s) <- lex r 
     (sh, t) <- readsPrec (app + 1) s 
     (xs, u) <- readsPrec (app + 1) t 
     return (R.fromList sh xs, u) 
    where app = 10 

Eğer StandaloneDeriving uzantısını kullanan durumunda ilk iki örneği kolaylaştırılabilir:

deriving instance Read Z 
deriving instance (Read tail, Read head) => Read (tail :. head) 

Bu örnekler muhtemelen Karoser kendisi olmalıdır; Ben sadece Text.Show ve repa'nın show çıktısında verilen örnek örneğini temel aldım. Repus'un bug tracker numaralı telefonuna bir özellik talebi yapmanızı ve bu örnekleri şu an için programınızın bir modülüne koymanızı öneriyorum (yetim örneklerinden tamamen kaçınmak istemiyorsanız, bu durumda sorunu başka bir şekilde tamamen çözmek zorunda kalacaksınız). Muhtemelen sadece (toList birlikte) bir listeye veri dönüştürme ve kullanmayı düşünmelisiniz söyledi


; yetim vakasından kaçınıyor ve herhangi bir olumsuz tarafa sahip olmamalı. Kodla verileri insan tarafından okunabilir hale getirmekten daha çok ilgileniyorsanız, cereal gibi bir "gerçek" serileştirme kitaplığı kullanmayı düşünebilirsiniz; Read genel olarak oldukça sınırlı kullanım olarak kabul edilir.

+0

'Array' yazın, 'Range' ve 'Generator 'içeren Bölgelerin bir listesinden yapılır; her iki Range bir Jeneratör bileşen olarak daha yüksek mertebeden işlevlere sahiptir, bu nedenle gerçekten Read örnekleri yapamazlar. –

+0

@stephentetley: Tüm 'Read' örneğinin yapabilmesi gereken, ilgili' Show' örneğinin çıktılarının geçerli Haskell kodunu ayrıştırmasıdır. – ehird

+0

'gösterir $ R.fromFunction (Z:. (10 :: Int)) (const 42)' = '" Dizi (Z: .10) [42.0,42.0,42.0,42.0,42.0,42.0,42.0,42.0, 42.0,42.0] ", örneğim doğru şekilde ayrıştırılıyor. – ehird