2015-07-20 81 views
1

我正在使用GHC泛型。我的用例几乎与the example in the wiki相同,只是我编码和解码基因序列。使用GHC.Generics时添加显示约束

这一切都工作正常,直到我决定保留我已经阅读的清单,以便我可以在发生错误时向用户报告。这意味着我需要添加一个Show约束到我的默认get实现。问题是我无法弄清楚如何编写约束。请参阅下面的代码中的-- HELP!!!评论。

{-# 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)) 

回答

2

D'oh!我应该使用的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 
+0

你或许应该接受这个答案。 – AJFarmar

+0

@AJFarmar我会的,但有一个延迟(3天?),然后才能接受你自己的答案。直到明天我都不能接受这个。 – mhwombat