Jaki jest najlepszy sposób, abyRepa --- Jak utworzyć instancję odczytu?
type Configuration = Array DIM1 (Double, Double, Double)
instancję czytać? Więc później mógłbym wyprowadzić jako instancję Czytaj również.
Jaki jest najlepszy sposób, abyRepa --- Jak utworzyć instancję odczytu?
type Configuration = Array DIM1 (Double, Double, Double)
instancję czytać? Więc później mógłbym wyprowadzić jako instancję Czytaj również.
Takim przykładem będzie orphan instance, którego należy zasadniczo unikać. Jednakże, jest to dość proste do napisania go:
{-# 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
Jeśli używasz rozszerzenia StandaloneDeriving
dwa pierwsze przypadki można uprościć:
deriving instance Read Z
deriving instance (Read tail, Read head) => Read (tail :. head)
te przypadki powinny prawdopodobnie w samej Repa; Właśnie oparłem je na przykładowej instancji podanej w Text.Show i wyjściu z repa na show
. Proponuję wysłanie prośby o funkcję do repa za bug tracker i umieszczenie tych instancji w module twojego programu na teraz (chyba, że chcesz całkowicie uniknąć osieroconych instancji, w takim przypadku będziesz musiał rozwiązać problem w zupełnie inny sposób).
Powiedział, że powinieneś rozważyć po prostu konwersji danych do listy (z toList
) i za pomocą tego; omija instancję osieroconą i nie powinien mieć żadnych wad. Możesz także rozważyć użycie "prawdziwej" biblioteki do serializacji, takiej jak cereal, jeśli bardziej interesuje Cię przetwarzanie danych za pomocą kodu niż czytanie w zrozumiały dla człowieka sposób; Read
jest generalnie uważany za raczej ograniczony użytek.
Typ 'Array' w Repa jest tworzony z listy regionów, które zawierają' Range' i 'Generator', oba Range an Generator mają funkcje wyższego rzędu jako komponenty, więc nie mogą być rzeczywiście tworzone w instancjach Read. –
@stephentetley: Cała instancja 'Read' musi być w stanie przetworzyć poprawny kod Haskella odpowiadający wyjściom instancji' Show'. – ehird
'show $ R.fromFunction (Z:. (10 :: Int)) (const 42)' = '" Array (Z:. 10) [42,42, 42,42, 42,0, 42,42, 42,0, 42,0, 42,0, 42.0,42.0] "', które moja instancja poprawnie analizuje. – ehird
Podejrzewam, że nie można utworzyć "pełnej" instancji odczytu. Ogólnie rzecz biorąc, ważne typy danych będą już mieć instancje odczytu, jeśli autor uzna, że mają sens. Typ 'Array' w Repa ma funkcje wyższego rzędu wewnątrz jego komponentów -' Generator' i 'Range', które nie mogą być tworzone jako instancje Read. Wyobrażam sobie, że właściwym rozwiązaniem jest przekształcenie/odserializowanie danych w prostszy format. –