Добавление ограничения Show при использовании GHC.Generics
Я использую 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))
1 ответ
Решение
D'о! Я должен был использовать 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