我想在Monad的trace
中插入bind
,但它需要Show
个实例,并且可以修改许多其他实例。
我看到this,似乎最后一个是最好的解决方案。但是没有完整的示例代码,而且我对这种语言扩展还没有足够的知识。
有没有更好的解决方案?以下代码有什么问题?
{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances, FlexibleContexts #-}
data STrue = STrue
data SFalse = SFalse
type family ShowPred a where
ShowPred Char = STrue
ShowPred [Char] = STrue
ShowPred a = SFalse
class Print' flag a where
print' :: flag -> a -> b -> b
instance Show a => Print' STrue a where
print' _ s v = traceShow s v
instance Print' SFalse a where
print' _ _ = id
instance (ShowPred [t] ~ flag, Print' flag [t]) => Monad (Parser t) where
return x = P (\ts-> Success ts x)
fail e = P (\ts-> Failure ts e)
(P f) >>= g = P (continue . f)
where
continue (Success ts x) = let (P g') = g x in {- print' (undefined :: flag) ts $ -} g' ts
continue (Committed r) = Committed (continue r)
continue (Failure ts e) = Failure ts e