2015-07-20 79 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