简体   繁体   English

使用GHC时添加显示约束

[英]Adding a Show constraint when using GHC.Generics

I am using GHC Generics. 我正在使用GHC仿制药。 My use case is almost identical to the example in the wiki , except that I am encoding and decoding gene sequences. 我的用例与Wiki中的示例几乎相同,除了我正在编码和解码基因序列。

This was all working fine, until I decided to keep a list of what I'd already read, so that I could report it to the user in case of an error. 一切正常,直到我决定保留已读内容的列表,以便在出现错误时可以将其报告给用户。 That means that I need to add a Show constraint to my default get implementation. 这意味着我需要在默认的get实现中添加Show约束。 The problem is that I can't figure out how to write the constraint. 问题是我不知道如何写约束。 See the -- HELP!!! 看到-- HELP!!! comment in the code below. 在下面的代码中添加注释。

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeOperators #-}

import Control.Monad.State.Lazy (StateT)
import qualified Control.Monad.State.Lazy as S (put, get, gets)
import Data.Functor.Identity (Identity)
import Data.Word (Word8, Word16)
import GHC.Generics

type Sequence = [Word8]

type Writer = StateT Sequence Identity

type Reader = StateT (Sequence, Int, [String]) Identity

class Genetic g where
  -- | Writes a gene to a sequence.
  put :: g -> Writer ()

  default put :: (Generic g, GGenetic (Rep g)) => g -> Writer ()
  put = gput . from

  -- | Reads the next gene in a sequence.
  get :: Reader (Either [String] g)

  default get :: (Generic g, GGenetic (Rep g), Show (Rep g x???)) -- HELP!!!
    => Reader (Either [String] g)
  get = do
    (_, start, _) <- S.get
    a <- gget
    (xs, stop, trace) <- S.get
    let msg = show start ++ ':' : show stop ++ ' ' : show a
    S.put (xs, stop, msg:trace)
    return $ fmap to a

class GGenetic f where
  gput :: f a -> Writer ()
  gget :: Reader (Either [String] (f a))

D'oh! D'哦! I should have used show (fmap to a) instead of show a .Then all I needed was to add Show g as a constraint.. This simple change compiles fine: 我应该使用show (fmap to a)而不是show a 。然后,我所需要的只是添加Show g作为约束。.这个简单的更改可以很好地编译:

  default get :: (Generic g, GGenetic (Rep g), Show g)
                => Reader (Either [String] g)
  get = do
    (_, start, _) <- S.get
    a <- gget
    (xs, stop, trace) <- S.get
    let result = fmap to a
    let msg = show start ++ ':' : show stop ++ ' ' : show result
    S.put (xs, stop, msg:trace)
    return result

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM