[英]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.