且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何调用可能会失败的构造函数,尤其是在实现' Read'时和'任意&#39 ;?

更新时间:2021-10-19 03:58:02

Read 类型类将解析表示为成功列表(失败与没有成功相同);因此,您应该返回 [] ,而不是 undefined .至于丢失有关出了什么问题的信息:是的,并且 readsPrec 的类型意味着您不能为此做太多事情.如果您确实确实想要[注意:我不认为您应该这样做],则可以围绕 EnigmaError EnigmaConfig 以外的对象定义一个新类型包装器,并为它提供一个 Read 实例成功解析了配置错误.

The Read typeclass represents parses as lists of successes (with failures being the same as no successes); so rather than undefined you should return []. As for losing information about what went wrong: that's true, and the type of readsPrec means you can't do much about that. If you really, really wanted to [note: I don't think you should want this] you could define a newtype wrapper around Except EnigmaError EnigmaConfig and give that a Read instance that had successful parses of configuration errors.

对于任意,您有两种选择.一种选择是所谓的拒绝采样.例如

For Arbitrary you have a couple choices. One choice is so-called rejection sampling; e.g.

arbitrary = do
    -- ...
    case configEnigma ... of
        Left err -> arbitrary -- try again
        Right v  -> return v

您还可以将任意实例视为内部API的一部分,并使用不安全的内部调用而不是使用安全的公共API来构造您的配置.其他选项包括调用 error fail .(我认为这四个选项大致按优先顺序排列-拒绝采样,然后是不安全的内部调用,然后是 error ,然后是 fail ,尽管您的判断可能有所不同.)

You might also consider an Arbitrary instance to be part of your internal API, and use unsafe, internal calls rather than using the safe, public API for constructing your configuration. Other options include calling error or fail. (I consider these four options to be in roughly preference order -- rejection sampling, then unsafe internal calls, then error, then fail -- though your judgement may differ.)