制作
的最佳方式是什么?type Configuration = Array DIM1 (Double, Double, Double)
Read的一个实例?所以后来我可以推导出
data SimulationData = SD Configuration Double StdGen Int
也是Read的一个实例。
答案 0 :(得分:6)
这样的实例将是orphan instance,您通常应该避免这种情况。但是,写它很简单:
{-# 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
如果您使用StandaloneDeriving
扩展名,则可以简化前两个实例:
deriving instance Read Z
deriving instance (Read tail, Read head) => Read (tail :. head)
这些实例应该可以自行修复;我只是基于Text.Show和repa show
输出中给出的示例实例。我建议在repa bug tracker上发出一个功能请求,并将这些实例放入程序的一个模块中(除非你想完全避免孤立实例,在这种情况下你必须完全以另一种方式解决问题) )。
也就是说,您应该考虑将数据转换为列表(使用toList
)并使用它;它避免了孤儿实例,并且不应该有任何缺点。如果您对使用代码处理数据更感兴趣而不是人类可读,您可能还需要考虑使用像cereal这样的“真实”序列化库; Read
通常被认为使用相当有限。