修复---如何制作一个Read实例?

Yro*_*irg 5 haskell repa

什么是最好的方法

type Configuration = Array DIM1 (Double, Double, Double)
Run Code Online (Sandbox Code Playgroud)

Read的一个实例?所以后来我可以推导出来

data SimulationData = SD Configuration Double StdGen Int
Run Code Online (Sandbox Code Playgroud)

成为Read的一个例子.

ehi*_*ird 6

这样的实例将是一个孤儿实例,您通常应该避免这种情况.但是,编写它非常简单:

{-# 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
Run Code Online (Sandbox Code Playgroud)

如果使用StandaloneDeriving扩展名,则可以简化前两个实例:

deriving instance Read Z
deriving instance (Read tail, Read head) => Read (tail :. head)
Run Code Online (Sandbox Code Playgroud)

这些实例应该可以自行修复; 我只是基于Text.Showrepashow输出中给出的示例实例.我建议在repa的bug跟踪器上发出一个功能请求,并将这些实例放入程序的一个模块中(除非你想完全避免孤立实例,在这种情况下你必须完全以另一种方式解决问题).


也就是说,您应该考虑简单地将数据转换为列表(使用toList)并使用它; 它避免了孤儿实例,并且不应该有任何缺点.您可能还想考虑使用像谷物这样的"真实"序列化库,如果您对使用代码处理数据更感兴趣而不是人类可读; Read通常认为使用相当有限.